2

当我尝试从麦克风播放声音时,我需要通过MediaStreamSource。 因此,我首先需要实现一个MediaStreamSource为我从麦克风获得的pcm波形。至少有两种方法我认为需要实施。起初MediaElement为什么不播放MediaStreamSource(在SilverLight中)?

protected override void OpenMediaAsync() { 
    // Create description 
    Dictionary<MediaStreamAttributeKeys, string> streamAttributes = new Dictionary<MediaStreamAttributeKeys, string>(); 
    streamAttributes[MediaStreamAttributeKeys.CodecPrivateData] = output.CodecPrivateData; 
    audioDesc = new MediaStreamDescription(MediaStreamType.Audio, streamAttributes); 

    // register stream 
    Dictionary<MediaSourceAttributesKeys, string> sourceAttributes = new Dictionary<MediaSourceAttributesKeys, string>(); 
    List<MediaStreamDescription> availableStreams = new List<MediaStreamDescription>(); 

    availableStreams.Add(audioDesc); 
    sourceAttributes[MediaSourceAttributesKeys.Duration] = TimeSpan.FromMinutes(0).Ticks.ToString(); // whatever I put here I get the same result. 
    sourceAttributes[MediaSourceAttributesKeys.CanSeek] = false.ToString(); 

    ReportOpenMediaCompleted(sourceAttributes, availableStreams); 
} 

这工作得很好。我的CodecPrivateData是'01000100401F0000803E0000020010000000'(PCM 1ch 16Bits 8kHz)。这种方法被调用通过设置来源如下:

WaveMediaStreamSource WaveStream = new WaveMediaStreamSource(output); 
mediaElement.SetSource(WaveStream); 
mediaElement.Play(); 

Play()之后absoultely什么也没有发生。我建议mediaElement应至少调用MediaStreamSource的方法GetSampleAsync()。但事实并非如此。我注意到MediaElement不再拨打任何电话给MediaStreamSource了。

虽然OpenMediaAsyncmediaElement.CurrentStateOpening。之后,它变成Playing,但它不起作用。然后它不再改变,并保持Playing

任何想法?

+0

我也看过[此示例](http://silverlightvideochat.codeplex.com/releases/view/43242)。它的实现非常相似,而且这部分几乎相同。 (除持续时间部分)唯一不同的是,它似乎每隔几毫秒切换一次'MediaStreamSource'。但是这不应该影响'GetSampleAsync()'永远不会被调用。我追踪的其余部分产生完全相同的数据。 –

+0

对于这个例子,我也能够重现这种行为,当我只分配一个'MediaStreamSource'并且阻止所有跟随时,它也不会触及流的'GetSampleAsync()'方法。这听起来像缓冲或类似的东西,'直到'已经分配了特定数量的'MediaStreamSource'对象。但是这对我来说绝对没有意义 - 否则我不明白。任何人的想法? –

回答

2

要得到这个底部,你需要检查MediaElement.CurrentState - 它会告诉你与MediaStreamSourceMediaElement被卡住的交互的哪个步骤。反过来,这将告诉您的哪些MediaStreamSource方法应区别impemented ...

对于全面演练,包括在缓冲部分必要的信息,请参阅http://msdn.microsoft.com/en-us/library/hh180779%28v=vs.95%29.aspx

+0

是的,我已经想过了,我知道这个链接。但是我的媒体元素告诉我这是'玩'。它从“Opening”变为“Playing”,然后什么也没有发生。 (我手动检查并通过'CurrentStateChanged'事件。) –

+0

@nemcija如果你读到底部的链接,你会发现这种行为可能发生在MediaElement发生“饿死”的情况下 - 你的描述与IMO。 – Yahia

+0

但是,如果从不请求BufferState,我该如何告诉mediaElement?我试图通过ReportGetSampleProgress(1)报告它;直接报告ReportOpenMediaCompleted后。但它没有什么区别。我也玩过'this.AudioBufferLength'。如果我问'mediaElement.BufferingProgress',它告诉我它已经填满了。 –

2

有些事情尝试...

尝试设置CanSeek为“0”并尝试一个大于零的持续时间,任何硬编码值都可以,至少可以试着让它工作。再次检查你的CodecPrivateData字符串,并确保它是正确的。

您也可以尝试从ManagedMediaHelpers project中下载Mp3MediaStreamSource,并首先确保应用程序中的其他内容正确设置,然后切换回您的自定义MediaStreamSource。

+0

我已经完成了所有这些。正如你可以在聊天协议中看到的,我已经尝试过不同的'MediaStreamSource'实现(&项目),但没有成功。目前我处于放弃silverlight的状态,因为它似乎是越野车。有时它起作用 - 有时不起作用 - 大多不是。 –

1

为Windows Phone(WP7.5和WP8)开发mediaElement时,出于完全超出我的原因,调试器不会在GetSampleAsync回调中的任何断点上断开,这是第一次调用回调!

调试器将在下一次到达断点时断开。尝试用此替换您的GetSampleAsync:

protected override void GetSampleAsync(MediaStreamType mediaStreamType) 
    { 
     System.Diagnostics.Debug.WriteLine("Yay!"); 

     MediaStreamSample msSamp = new MediaStreamSample(
      _videoDesc, _frameStream, _frameStreamOffset, 
      _frameBufferSize, _currentTime, _emptySampleDict); 

     ReportGetSampleCompleted(msSamp); 
    } 
+0

与Silverlight5 VS2012相同的行为 – tpol