2

When I try to stream sound from my microphone, I need to get it through a MediaStreamSource. Therefore I first need to implement a MediaStreamSource for the pcm waveformat I get from my Microphone. There are at least two methods I think I need to implement. At first

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

This works very well. My CodecPrivateData is '01000100401F0000803E0000020010000000' (PCM 1ch 16Bits 8kHz). This method gets called by setting the source as here:

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

After Play() absoultely nothing happens. I would suggest the mediaElement should call at least once the method GetSampleAsync() of the MediaStreamSource. But it doesn't. I've noticed that the MediaElement doesn't make any call to the MediaStreamSource anymore.

While OpenMediaAsync the mediaElement.CurrentState is Opening. After that it turns to Playing but it doesn't play. And then it do not change anymore and remains Playing.

Any Ideas?

Christoph Meißner
  • 1,511
  • 2
  • 21
  • 40
  • I have also looked at [this example](http://silverlightvideochat.codeplex.com/releases/view/43242). It is implemented very similar, and for this part above nearly the same. (except the duration part) The only thing that is different, that it seems to switch the `MediaStreamSource` every few milliseconds. But this should not influence that `GetSampleAsync()` is never called. The rest I've traced produces exact the same data. – Christoph Meißner Nov 12 '11 at 11:45
  • For this example I am also able to reproduce this behaviour, when I only assign one `MediaStreamSource` and block all following, it also never touches the `GetSampleAsync()`-Method of the stream. This smells like buffering or something like that, 'until' a specific count of `MediaStreamSource`-objects have been assigned. But this makes absolutely no sense to me - or I don't understand it. Anyone an idea? – Christoph Meißner Nov 12 '11 at 19:25

3 Answers3

2

To get to the bottom of this you need to check MediaElement.CurrentState - it will tell you at which step of the interaction with the MediaStreamSource the MediaElement is stuck. This in turn will tell which of your MediaStreamSource methods should be impemented differently...

For a comprehensive walkthrough including essential information on the buffering part see http://msdn.microsoft.com/en-us/library/hh180779%28v=vs.95%29.aspx

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Yes I already thought about that and I know that link. But my mediaElement tells me that it is `Playing`. It changes from `Opening` to `Playing` and then nothing happens anymore. (I check it manually and via `CurrentStateChanged`-Event.) – Christoph Meißner Nov 14 '11 at 15:50
  • @nemcija if you read that link to the bottom you will find that this behaviour can happen when the MediaElement has a case of "starving" - your description is consistent with that IMO. – Yahia Nov 14 '11 at 16:10
  • But how should I tell the mediaElement about the BufferState when it never asks for it? I've tried to report it by `ReportGetSampleProgress(1);` directly after reporting `ReportOpenMediaCompleted`. But it doesn't make a difference. I have also played around with `this.AudioBufferLength`. And if I ask the `mediaElement.BufferingProgress` it tells me it is filled. – Christoph Meißner Nov 14 '11 at 16:23
  • @nemcija since I don't have your situation I can only suggest to implement the `LogReady` event (http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.logready%28v=VS.95%29.aspx) and then call `RequestLog` (http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.requestlog%28v=VS.95%29.aspx) and see what it reports - it may the missing hint... – Yahia Nov 14 '11 at 16:54
  • Okay thats something i have not looked at until now. But it seems as if the call of `RequestLog()` doesn't have any effect. The `LogReady`-Event is never raised in any case. For me it seems as if the `MediaElement` is "deadlocked" or something like that. – Christoph Meißner Nov 14 '11 at 17:10
  • @nemcija that seems to indicate that the MediaElement internally is in `Closed` state thus meaning something it from from the source made it quit... can you trace it in the emulator ? – Yahia Nov 14 '11 at 17:18
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/4988/discussion-between-nemcija-and-yahia) – Christoph Meißner Nov 14 '11 at 17:19
  • 2
    Okay. I've got my answer: For me it means that **silverlight is buggy** (at least on some systems), and I'll **waste no time** anymore towards silverlight. – Christoph Meißner Nov 20 '11 at 20:19
2

Some things to try...

Try setting CanSeek to "0" and try a duration greater than zero, any hard coded value is fine to at least try to get it working. Also double check your CodecPrivateData string and make sure it's correct.

You also may want to try dropping in the Mp3MediaStreamSource from the ManagedMediaHelpers project and get that working first to make sure everything else in your app is set up properly then switch back to your custom MediaStreamSource.

Bill Reiss
  • 3,460
  • 1
  • 19
  • 20
  • I've done all of that already. As you can read in the chatprotocol I've already tried different `MediaStreamSource` implementations (& projects) without success. Currently I'm at the state to drop silverlight because it seems to be buggy. Sometimes it works - sometimes not - mostly not. – Christoph Meißner Nov 18 '11 at 17:55
1

When developing a mediaElement for Windows Phone (WP7.5 and WP8), for a reason that is completely beyond me, the debugger will not break on any breakpoints in the GetSampleAsync callback, the first time the callback is called !

The debugger will break the next time the breakpoint(s) will be reached. Try replacing your GetSampleAsync with this:

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

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

        ReportGetSampleCompleted(msSamp);
    }
Berthier Lemieux
  • 3,785
  • 1
  • 25
  • 25