Jon Rea Jon Rea - 8 months ago 66
C# Question

Sharing Media Playback Between Pages with Windows Phone 7 Media Player

What I want to achieve:


  • I want to initiate audio playback from an mp3 and/or aac HTTP stream in a WP7 application

  • I want to initiate playback from a specific 'PhoneApplicationPage' instance, but still allow navigation to other pages whilst maintaining playback without any interuption - i.e. I want playback to be 'application-scope'

  • I want to be able to 'seek' within my media

  • I playback to continue whilst the phone is locked



What I have tried:

MediaElement:


  • If the MediaElement is not owned by a page, no sound is produced when Play() is called, despite no exceptions being thrown.

  • After following 'http://blog.jayway.com/2010/10/04/enable-background-audio-for-multiple-pages-in-windows-phone-7/', playback still resets between page transitions

  • It also seems like a quite a hacky way of doing things...



Microsoft.Xna.Framework.MediaPlayer:


  • Works, but "MediaPlayer.PlayPosition" is read-only, and there is no seek method.

  • See post: 'http://forums.create.msdn.com/forums/t/17318.aspx' - Apparently this is by design due to XBox constraints with Xna (?!)



Microsoft Silverlight Media Framework:


  • http://smf.codeplex.com/

  • My favourite option, as it seems very comprehensive

  • Downloaded 'Silverlight Media Framework 2.3, WP7 specific' assemblies from:
    http://smf.codeplex.com/releases/view/57991#DownloadId=190196

  • I know this is hacky, but to get something working, in the code below, the 'SMFPlayer' is static, and added to each page's layout on navigation.

  • If the 'SMFPlayer' is not owned by a page, no sound is produced when Play() is called, despite no exceptions being thrown.

  • Playback still resets between page transitions...

  • Code:



using System;
using System.Diagnostics;
using Microsoft.Phone.Controls;
using Microsoft.SilverlightMediaFramework.Core;
using Microsoft.SilverlightMediaFramework.Core.Media;
using Microsoft.SilverlightMediaFramework.Plugins.Primitives;

namespace WindowsPhoneApplication1
{
public partial class MainPage : PhoneApplicationPage
{
public static readonly SMFPlayer Player = new SMFPlayer();

static MainPage()
{
Player.VolumeLevel = 1.0f;
Player.Playlist.Add(new PlaylistItem {MediaSource = new Uri("http://smf.vertigo.com/videos/wildlife.wmv", UriKind.Absolute)});

Player.LogLevel = LogLevel.All;
Player.LogEntryReceived += PlayerLogEntryReceived;
}

// Constructor
public MainPage()
{
InitializeComponent();
}

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
LayoutRoot.Children.Add(Player);
}

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
LayoutRoot.Children.Remove(Player);
}

private static void PlayerLogEntryReceived(object sender, CustomEventArgs<LogEntry> e)
{
Debug.WriteLine(e.Value.Severity + e.Value.Message + e.Value.Type);
}

private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
{
this.NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute));
}
}
}


Does anyone have any idea how I can satisfy my requirements?
Example code?

From an architectural point of view, what I really want is a Media Service which i can send streaming URLs to without caring about which page is currently shown.

Answer Source

I eventually found a simple, but effective solution: http://blog.reis.se/post/Enable-background-audio-for-multiple-pages-in-Windows-Phone-7-e28093-Take-2.aspx

In App.xaml:

<APPLICATION.RESOURCES>
    <MEDIAELEMENT x:key="GlobalMedia"></MEDIAELEMENT>
</APPLICATION.RESOURCES>

In App.xaml.cs:

public static MediaElement GlobalMediaElement
{
  get { return Current.Resources["GlobalMedia"] as MediaElement; }
}

In your page:

public partial class MyPage : PhoneApplicationPage
{
    MediaElement MEAudio;

    public MainPage()
    {
        InitializeComponent();    
        MEAudio = App.GlobalMediaElement;
    }

    private void OnSomeEvent(object sender, RoutedEventArgs e)
    {
        MEAudio.xxxxx();
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download