使用MediaStreamSource解码音频

时间:2016-03-18 12:18:12

标签: audio win-universal-app mediastreamsource

我有一个UWP项目,我想使用Windows.Media.Audio API来播放文件。我没有使用FileInputNode,而是想流式传输文件,以便精确确定各种时序属性。

我找到了MediaStreamSource API并制作了以下代码,试图解码16位PCM 2通道.wav文件

 public async Task<Windows.Storage.Streams.Buffer> GetBuffer()
    {
        // check if the sample requested byte offset is within the file size 

        if (byteOffset + BufferSize <= mssStream.Size)
        {
            inputStream = mssStream.GetInputStreamAt(byteOffset);

            // create the MediaStreamSample and assign to the request object.  
            // You could also create the MediaStreamSample using createFromBuffer(...) 

            MediaStreamSample sample = await MediaStreamSample.CreateFromStreamAsync(inputStream, BufferSize, timeOffset);
            sample.Duration = sampleDuration;
            sample.KeyFrame = true;
            // increment the time and byte offset 

            byteOffset += BufferSize;
            timeOffset = timeOffset.Add(sampleDuration);


            return sample.Buffer;
        }
        else
        {

            return null;
        }
    }

我没有使用Event系统,只要我的AudioFrameInputNode需要一个新的AudioFrame,我就会触发一个方法。

现在看来,MediaStreamSample中生成的字节数组与使用DataReader读取StorageFile时的结果完全相同。

MediaStreamSample.CreateFromStreamAsync实际上是否将音频文件解码为浮点字节数组?或者在播放样本时是在MediaElement中完成的吗?

如果是这样,我如何解码音频文件,以便将生成的AudioBuffer提供回我的FrameInputNode?

1 个答案:

答案 0 :(得分:1)

MediaStreamSample.CreateFromStreamAsync完成时,它会将新文件作为MediaStreamSample返回。

如果我理解你想要的是什么,以及你可以做些什么来完成它。

function sampleRequestedHandler(e) {
    var request = e.request;
    if (!MyCustomFormatParser.IsAtEndOfStream(randomAccessStream)) { 
        var deferral = request.getDeferral();
        var inputStream = MyCustomFormatParser.getInputStream(randomAccessStream); 
        MediaStreamSample.createFromStreamAsync(inputStream, sampleSize, timeOffset).
            then(function(sample) {
                sample.duration = sampleDuration;  
                sample.keyFrame = true;  
                request.sample = sample;           
                deferral.complete();  
            });
        }
}
  

请求样本时,您的自定义解析器会从中提取音频数据   RandomAccessStream并返回仅音频样本的InputStream