我正在为 Windows Phone 8.1 开发录音机应用程序,该应用程序将录音存储在本地存储和云存储服务上。
除了可以暂停正在进行的录制之外,所有内容几乎都已完成,这是对此应用程序的强烈要求,我必须完成它。 现在,由于 PauseRecordAsync() 和 ResumeRecordAsync() 不适用于MediaCapture类中的Windows Phone 8.1,它们将在Windows 10中可用,我不得不做一个解决方法:每次按下暂停按钮,音频块都保存在临时文件夹中,该文件存储在一个数组中。按下停止按钮时,最后一个块存储在数组中,并调用以下连接函数并创建最终的音频临时文件:
public async Task<IStorageFile> ConcatenateAudio([ReadOnlyArray]IStorageFile[] audioFiles, IStorageFolder outputFolder, string outputfileName)
{
IStorageFile _OutputFile = await outputFolder.CreateFileAsync(outputfileName, CreationCollisionOption.ReplaceExisting);
MediaComposition _MediaComposition = new MediaComposition();
MediaEncodingProfile _MediaEncodingProfile = MediaEncodingProfile.CreateM4a(AudioEncodingQuality.High);
foreach (IStorageFile _AudioFile in audioFiles)
{
if(_AudioFile != null)
{
BackgroundAudioTrack _BackgroundAudioTrack = await BackgroundAudioTrack.CreateFromFileAsync(_AudioFile);
MediaClip _MediaClip = MediaClip.CreateFromColor(Windows.UI.Colors.Black, _BackgroundAudioTrack.TrimmedDuration); // A dummy black video is created witn the size of the current audio chunk.
// Without this, the duration of the MediaComposition object is always 0.
// It's a messy workaround but it gets the job done.
// Windows 10 will dirrectly support PauseRecordAsync() and ResumeRecordAsync() for MediaCapture tho'. Yay! :D
_MediaClip.Volume = 0;
_BackgroundAudioTrack.Volume = 1;
_MediaComposition.Clips.Add(_MediaClip);
_MediaComposition.BackgroundAudioTracks.Add(_BackgroundAudioTrack);
}
}
TranscodeFailureReason _TranscodeFailureReason = await _MediaComposition.RenderToFileAsync(_OutputFile, MediaTrimmingPreference.Fast, _MediaEncodingProfile);
if (_TranscodeFailureReason != TranscodeFailureReason.None)
{
throw new Exception("Audio Concatenation Failed: " + _TranscodeFailureReason.ToString());
}
return _OutputFile;
}
问题是当我播放文件时,所有音频块都是从最终音频文件的开头同时播放而不是播放第二个音频块一个在第一个结束后立即,依此类推。他们都在一对一上演。另一方面,文件的长度是正确,在所有音频文件播放完毕后,它会完全沉默。
答案 0 :(得分:2)
我明白了。我必须为 BackgroundAudioTrack 手动设置延迟。 这是工作代码:
public async Task<IStorageFile> ConcatenateAudio([ReadOnlyArray]IStorageFile[] audioFiles, IStorageFolder outputFolder, string outputfileName)
{
IStorageFile _OutputFile = await outputFolder.CreateFileAsync(outputfileName, CreationCollisionOption.ReplaceExisting);
MediaComposition _MediaComposition = new MediaComposition();
MediaEncodingProfile _MediaEncodingProfile = MediaEncodingProfile.CreateM4a(AudioEncodingQuality.High);
TimeSpan totalDelay = TimeSpan.Zero;
foreach (IStorageFile _AudioFile in audioFiles)
{
if (_AudioFile != null)
{
BackgroundAudioTrack _BackgroundAudioTrack = await BackgroundAudioTrack.CreateFromFileAsync(_AudioFile);
MediaClip _MediaClip = MediaClip.CreateFromColor(Windows.UI.Colors.Black, _BackgroundAudioTrack.TrimmedDuration); // A dummy black video is created witn the size of the current audio chunk.
// Without this, the duration of the MediaComposition object is always 0.
// It's a messy workaround but it gets the job done.
// Windows 10 will dirrectly support PauseRecordAsync() and ResumeRecordAsync() for MediaCapture tho'. Yay! :D
_MediaClip.Volume = 0;
_BackgroundAudioTrack.Volume = 1;
_MediaComposition.Clips.Add(_MediaClip);
_MediaComposition.BackgroundAudioTracks.Add(_BackgroundAudioTrack);
_BackgroundAudioTrack.Delay = totalDelay;
totalDelay += _BackgroundAudioTrack.TrimmedDuration;
}
}
TranscodeFailureReason _TranscodeFailureReason = await _MediaComposition.RenderToFileAsync(_OutputFile, MediaTrimmingPreference.Fast, _MediaEncodingProfile);
if (_TranscodeFailureReason != TranscodeFailureReason.None)
{
throw new Exception("Audio Concatenation Failed: " + _TranscodeFailureReason.ToString());
}
return _OutputFile;
}