WP8.1 - C# - 使用 MediaComposition 重叠音频 class

WP8.1 - C# - Overlapping audio with MediaComposition class

我正在为 Windows Phone 8.1 开发一个 录音机 应用程序,将录音存储在本地存储和云存储服务。

一切都差不多完成了,除了能够暂停正在进行的录音是这个应用程序的强烈要求,我必须完成它。 现在,由于 PauseRecordAsync()ResumeRecordAsync()在 MediaCapture class 中不适用于 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;
    }

问题是当我播放文件时,所有音频块都是从最终音频文件的开头同时播放 而不是在第一个结束后立即播放第二个,依此类推。他们都在一个接一个地玩。另一方面,文件的长度正确,所有音频文件播放完后,完全没有声音。

我明白了。我不得不为 BackgroundAudioTrack 手动设置 delay。 这是工作代码:

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;
    }