Hello,
I'm writing a small application which requires to start audio file playback at a specified position in milliseconds. To accomplish this, I use this code:
/// <summary>
/// Initializes the AudioGraph
/// </summary>
/// <param name="renderDevice">The audio render device (speaker)</param>
/// <returns>true on success</returns>
private async Task<bool> InitAudioGraph(DeviceInformation renderDevice = null)
{
if (audioGraph != null) return true;
var audioGraphSettings = new AudioGraphSettings(AudioRenderCategory.Media)
{
PrimaryRenderDevice = renderDevice
};
var result = await AudioGraph.CreateAsync(audioGraphSettings);
if (result.Status == AudioGraphCreationStatus.Success)
{
this.audioGraph = result.Graph;
return true;
}
return false;
}
/// <summary>
/// Plays the given audio file.
/// </summary>
/// <param name="file"></param>
/// <param name="startMillis">If provided, playback will be started at the appropriate position in the file</param>
/// <param name="endMillis">If provided, playback will be stopped at the appropriate position in the file</param>
/// <returns></returns>
public async Task<bool> PlayFile(StorageFile file, float startMillis = 0, float endMillis = 0)
{
if (await InitAudioGraph())
{
this.playFile = file;
this.playFileEndMillis = endMillis;
// prepare and playback recorded audio data
var deviceResult = await audioGraph.CreateDeviceOutputNodeAsync();
if (deviceResult.Status != AudioDeviceNodeCreationStatus.Success) return false;
var outputNode = deviceResult.DeviceOutputNode;
var playback = await audioGraph.CreateFileInputNodeAsync(file);
if (playback.Status != AudioFileNodeCreationStatus.Success) return false;
var fileInputNode = playback.FileInputNode;
fileInputNode.AddOutgoingConnection(outputNode);
// set the start time
if (startMillis > 0)
{
var startTime = TimeSpan.FromMilliseconds(startMillis);
if (startTime < fileInputNode.Duration)
{
fileInputNode.Seek(startTime);
}
}
// set the end time
if (endMillis > 0)
{
var endTime = TimeSpan.FromMilliseconds(endMillis);
if (endTime <= fileInputNode.Duration)
{
fileInputNode.EndTime = endTime;
}
}
// start playback
audioGraph.Start();
return true;
}
return false;
}
This is working fine when using uncompressed audio files like *.wav - however, when using *.mp3, the playback begins at various locations somewhere around the specified startMillis. In my test case, it could be about 1s differing from the specified startMillis. I compared this with an audio editing tool.
How can I establish that an mp3-file starts at the exact specified position in the audio file? I already tried to change fileInputNode.Seek to fileInputNote.StartTime = startTime which has the same result as fileinputNode.Seek.
Thanks in advance,
Manuel Kurtz