原文:与众不同 windows phone (15) - Media(媒体)之后台播放音频

[索引页]
[源码下载]

与众不同 windows phone (15) - Media(媒体)之后台播放音频

作者:webabcd

介绍
与众不同 windows phone 7.5 (sdk 7.1) 之媒体

  • 通过 AudioPlayerAgent 实现在后台播放音频

示例
演示如何通过后台代理的方式来实现音频在后台的播放
1、后台代理
MyAudioPlayerAgent/AudioPlayer.cs

/*
* 本例演示如何播放后台音频(以 AudioPlayerAgent 为例,另 AudioStreamingAgent 用于流式播放音频)
* 建议使用 AudioPlaybackAgent 类型的模板创建此项目
*
* BackgroundAgent - 后台代理类,抽象类,它是 ScheduledTaskAgent、AudioPlayerAgent 和 AudioStreamingAgent 的基类
* NotifyComplete() - 用于通知系统,代理已经完成了当前的任务,调用此方法后,系统才会去准备执行下一次任务
* Abort() - 用于通知系统,放弃此次和以后的任务
* OnCancel() - 后台代理被取消时所执行的方法(由系统调用,比如后台代理转到休眠状态或终止状态前会调用此方法)
*
* AudioPlayerAgent - 后台播放音频的代理类
* OnError() - 当播放中出现错误时,系统会调用此方法
* OnPlayStateChanged() - 当播放状态发生改变时,系统会调用此方法(错误状态除外)
* OnUserAction() - 当程序改变播放行为时,系统会调用此方法
*
* PlayState - Microsoft.Phone.BackgroundAudio.PlayState 枚举
* Unknown, Stopped, Paused, Playing, BufferingStarted, BufferingStopped, TrackReady, TrackEnded, Rewinding, FastForwarding, Shutdown, Error
*
* UserAction - Microsoft.Phone.BackgroundAudio.UserAction 枚举
* Stop, Pause, Play, SkipNext, SkipPrevious, FastForward, Rewind, Seek
*
* AudioTrack - 音频对象
* Source - 音频的地址,远程地址或独立存储地址均可
* Title - 音频名称
* Duration - 音频时长
* Album - 专辑名称
* AlbumArt - 专辑封面的 Uri 地址,远程地址或独立存储地址均可,如果使用独立存储地址则其目录必须是 Shared/Media
* Artist - 艺术家
* PlayerControls - 锁屏等状态下的播放器控件显示(Microsoft.Phone.BackgroundAudio.EnabledPlayerControls 枚举)
* None = 0, SkipNext = 1, SkipPrevious = 2, FastForward = 4, Rewind = 8, Pause = 16, All = 31
* Tag - 任意内容,即为 AudioTrack 绑定一个上下文数据
* BeginEdit() - 将 AudioTrack 设置为编辑状态(如果需要修改 AudioTrack 的属性则需要将 AudioTrack 设置为编辑状态)
* EndEdit() - 结束 AudioTrack 的编辑状态
*/ using System;
using System.Windows;
using Microsoft.Phone.BackgroundAudio; using System.Collections.Generic; namespace MyAudioPlayerAgent
{
public class AudioPlayer : AudioPlayerAgent
{
// 播放列表
private static List<AudioTrack> _playList = new List<AudioTrack>
{
new AudioTrack(new Uri("SuperMario.mp3", UriKind.Relative), "title", "artist", "album", null, null, EnabledPlayerControls.Pause),
new AudioTrack(new Uri("http://traffic.libsyn.com/wpradio/WPRadio_29.mp3", UriKind.Absolute), "标题", "艺术家", "专辑", null, null, EnabledPlayerControls.All)
}; // 当前播放的 Track 在整个播放列表中的位置
private static int _currentTrackNumber = ; /*
* _classInitialized - 用于标记 AudioPlayer 是否已经被初始化
* 标记成 volatile 是为了避免编译器认为此字段无外部修改,而将其优化放入寄存器(标记成 volatile 的字段只会放在内存中)
* 一般来说,多任务环境下各任务间共享的字段应该被标记为 volatile
*/
private static volatile bool _classInitialized; public AudioPlayer()
{
if (!_classInitialized)
{
_classInitialized = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate
{
Application.Current.UnhandledException += AudioPlayer_UnhandledException;
});
}
} private void AudioPlayer_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
} // 播放状态发生改变时所调用的方法
protected override void OnPlayStateChanged(BackgroundAudioPlayer player, AudioTrack track, PlayState playState)
{
switch (playState)
{
case PlayState.TrackReady:
player.Play();
break;
case PlayState.TrackEnded:
PlayNextTrack(player);
break;
case PlayState.Playing:
break;
case PlayState.Paused:
break;
case PlayState.Stopped:
break;
case PlayState.BufferingStarted:
break;
case PlayState.BufferingStopped:
break;
case PlayState.Rewinding:
break;
case PlayState.FastForwarding:
break;
case PlayState.Shutdown:
break;
case PlayState.Unknown:
break;
} NotifyComplete();
} // 当程序改变播放行为时所调用的方法
protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param)
{
switch (action)
{
case UserAction.Play:
PlayTrack(player);
break;
case UserAction.SkipPrevious:
PlayPreviousTrack(player);
break;
case UserAction.SkipNext:
PlayNextTrack(player);
break;
case UserAction.Rewind:
player.Rewind();
break;
case UserAction.FastForward:
player.FastForward();
break;
case UserAction.Seek:
player.Position = (TimeSpan)param;
break;
case UserAction.Pause:
player.Pause();
break;
case UserAction.Stop:
player.Stop();
break;
} NotifyComplete();
} // 播放下一个 Track
private void PlayNextTrack(BackgroundAudioPlayer player)
{
if (++_currentTrackNumber >= _playList.Count)
_currentTrackNumber = ; PlayTrack(player);
} // 播放上一个 Track
private void PlayPreviousTrack(BackgroundAudioPlayer player)
{
if (--_currentTrackNumber < )
_currentTrackNumber = _playList.Count - ; PlayTrack(player);
} // 播放当前 Track
private void PlayTrack(BackgroundAudioPlayer player)
{
player.Track = _playList[_currentTrackNumber];
} // 出现异常时所调用的方法
protected override void OnError(BackgroundAudioPlayer player, AudioTrack track, Exception error, bool isFatal)
{
if (isFatal)
Abort();
else
NotifyComplete();
} // 当后台代理转到休眠状态或终止状态前,系统会自动调用此方法,需要在 5 秒内执行完毕
protected override void OnCancel()
{ }
}
} /*
* 主程序引用此项目后,会在 manifest 中添加如下信息:
* <ExtendedTask Name="BackgroundTask">
* <BackgroundServiceAgent Specifier="AudioPlayerAgent" Name="MyAudioPlayerAgent" Source="MyAudioPlayerAgent" Type="MyAudioPlayerAgent.AudioPlayer" />
* </ExtendedTask>
*/

2、前台调用后台代理播放音频
BackgroundAudio.xaml

<phone:PhoneApplicationPage
x:Class="Demo.Media.BackgroundAudio"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <StackPanel Orientation="Vertical">
<Button x:Name="btnPrev" Content="上一首" Click="btnPrev_Click" />
<Button x:Name="btnRewind" Content="快退" Click="btnRewind_Click" />
<Button x:Name="btnPlay" Content="播放" Click="btnPlay_Click" />
<Button x:Name="btnFastForward" Content="快进" Click="btnFastForward_Click" />
<Button x:Name="btnNext" Content="下一首" Click="btnNext_Click" /> <TextBlock x:Name="lblCurrentTrack" />
<TextBlock x:Name="lblPosition" />
</StackPanel> </Grid> </phone:PhoneApplicationPage>

BackgroundAudio.xaml.cs

/*
* 本例演示如何播放后台音频
*
* BackgroundAudioPlayer - 提供调用后台播放音频的相关功能
* Instance - 返回 BackgroundAudioPlayer 实例
* Track - 当前的 AudioTrack 对象。说明参见:MyAudioPlayerAgent/AudioPlayer.cs
* PlayerState - 播放器状态(Microsoft.Phone.BackgroundAudio.PlayState 枚举)。说明参见:MyAudioPlayerAgent/AudioPlayer.cs
* Position - 当前 AudioTrack 的播放位置
* CanPause - 是否可暂停
* CanSeek - 是否可以设置 Position 属性
* BufferingProgress - 缓冲百分比(0 - 1之间)
* Volume - 音量(0 - 1之间,默认值为 0.85)。注:目前 wp 没有提供 uvc(Universal Volume Control) 的接口
*
* Play - 播放当前 AudioTrack 的当前位置
* Pause - 暂停
* Stop - 停止
* Rewind - 快退
* FastForward - 快进
* SkipPrevious - 跳至上一个音频
* SkipNext - 跳至下一个音频
* Close - 关闭并释放所有资源
*
* PlayStateChanged - PlayState 发生改变时所触发的事件
*/ using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls; using Microsoft.Phone.BackgroundAudio;
using System.Windows.Navigation;
using System.IO.IsolatedStorage;
using System.Windows.Resources; namespace Demo.Media
{
public partial class BackgroundAudio : PhoneApplicationPage
{
public BackgroundAudio()
{
InitializeComponent(); Init();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
ProcessPlayState();
} private void Init()
{
// 由于播放本地音频时只能从独立存储中播放,所以此处把示例用音频文件从程序包中复制到独立存储
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!storage.FileExists("SuperMario.mp3"))
{
StreamResourceInfo resource = Application.GetResourceStream(new Uri("Assets/SuperMario.mp3", UriKind.Relative)); using (IsolatedStorageFileStream file = storage.CreateFile("SuperMario.mp3"))
{
int chunkSize = ;
byte[] bytes = new byte[chunkSize];
int byteCount; while ((byteCount = resource.Stream.Read(bytes, , chunkSize)) > )
{
file.Write(bytes, , byteCount);
}
}
}
} CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering); BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);
} // 实时更新当前音频播放的位置
void CompositionTarget_Rendering(object sender, EventArgs e)
{
if (BackgroundAudioPlayer.Instance != null)
lblPosition.Text = BackgroundAudioPlayer.Instance.Position.TotalSeconds.ToString();
} void Instance_PlayStateChanged(object sender, EventArgs e)
{
ProcessPlayState();
} void ProcessPlayState()
{
// 指定播放按钮是显示“播放”还是“暂停”
switch (BackgroundAudioPlayer.Instance.PlayerState)
{
case PlayState.Playing:
btnPlay.Content = "暂停";
break; case PlayState.Paused:
case PlayState.Stopped:
btnPlay.Content = "播放";
break;
} // 显示音频的 Title 和 Artist
if (BackgroundAudioPlayer.Instance.Track != null)
lblCurrentTrack.Text = BackgroundAudioPlayer.Instance.Track.Title + " by " + BackgroundAudioPlayer.Instance.Track.Artist;
} // 播放或暂停音频
private void btnPlay_Click(object sender, RoutedEventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
{
BackgroundAudioPlayer.Instance.Pause();
}
else
{
BackgroundAudioPlayer.Instance.Play();
}
} // 跳至下一首音频
private void btnNext_Click(object sender, RoutedEventArgs e)
{
BackgroundAudioPlayer.Instance.SkipNext();
} // 跳至上一首音频
private void btnPrev_Click(object sender, RoutedEventArgs e)
{
BackgroundAudioPlayer.Instance.SkipPrevious();
} // 快退
private void btnRewind_Click(object sender, RoutedEventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
BackgroundAudioPlayer.Instance.Rewind();
} // 快进
private void btnFastForward_Click(object sender, RoutedEventArgs e)
{
if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
BackgroundAudioPlayer.Instance.FastForward();
}
}
}

OK
[源码下载]

与众不同 windows phone (15) - Media(媒体)之后台播放音频的更多相关文章

  1. 与众不同 windows phone (16) - Media(媒体)之编辑图片, 保存图片到相册, 与图片的上下文菜单“应用程序...”和“共享...”关联, 与 Windows Phone 的图片中心集成

    原文:与众不同 windows phone (16) - Media(媒体)之编辑图片, 保存图片到相册, 与图片的上下文菜单"应用程序..."和"共享..." ...

  2. 与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成

    原文:与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成 [索引页][源码下载] 与众不同 win ...

  3. 第8月第15天 app支持后台播放

    1. AVAudioSession *audioSession = [AVAudioSession sharedInstance]; //默认情况下扬声器播放 [audioSession setCat ...

  4. iOS后台播放音乐

    iOS实现在后台播放音乐 iOS4之后就支持后台播放音频了.只需下面两步就可以实现后台播放音频操作了. 1. 在Info.plist中,添加"Required background mode ...

  5. iOS AvPlayer AvAudioPlayer音频的后台播放问题

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

  6. iOS设备后台播放音乐方法

    iOS设备后台播放音乐方法 1 在设置Capabliites中打开Background Modes,选择Audio And AirPlay 2 在控制viewDidLoad中添加下面代码 AVAudi ...

  7. iOS 后台播放音乐

    在info.plist文件中添加 下面是后台播放音频的完整测试代码: 引入文件<AVFoundation/AVFoundation.h> //后台播放音频设置 AVAudioSession ...

  8. iOS- 关于AVAudioSession的使用——后台播放音乐

    1.前言 •AVAudioSession是一个单例,无需实例化即可直接使用.AVAudioSession在各种音频环境中起着非常重要的作用 •针对不同的音频应用场景,需要设置不同的音频会话分类   1 ...

  9. IOS后台运行 之 后台播放音乐

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

随机推荐

  1. WPF-22:WPF绘制五角星改进版(增加半个五角星的绘制)-修改bug

    之前用坐标画多边形的方法,绘制五角星.今天调试时发现当时写的时候有bug,修改一下. 原文: http://blog.csdn.net/yysyangyangyangshan/article/deta ...

  2. 编程算法 - 扑克牌的顺子 代码(C)

    扑克牌的顺子 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 从扑克牌中随机抽取5张牌, 推断是不是一个顺子, 即这5张牌是不是连续的. 2~1 ...

  3. ASP.NET给Table动态添加删除行,并且得到控件的值

    ASP.NET给Table动态添加控件并且得到控件的值 由于跟老师做一个小的项目,可是我自己又不太懂js,所以一直为动态建立表格并且能动态的取值和赋值感到苦恼.起初在网上找到了一些js资源,解决了动态 ...

  4. Rabbit.Rpc

    .NET轻量级RPC框架:Rabbit.Rpc 最近准备写一个.NET的管理平台应用在公司,由于存在大量的Client => Server,Server => Client的请求需求在加上 ...

  5. WPF常用转换

    原文 WPF常用转换 以下是代码中常常用到的一些转换,整理如下,后续再不断完善: 1.string和Color的转换 //string转Color (Color)ColorConverter.Conv ...

  6. MSSQL - Sqlcommand

    Command对象:·Command对象也称为数据库连接对象,Command对象主要执行包括添加.删除.修改.查询数据的操作命令.也可以用来执行存储过程. 属性:CommandType属性. 执行存储 ...

  7. virtualbox从.VDI备份文件新建/恢复虚拟机(包括恢复各个备份节点)

    一.前言: ubuntu上的virtualbox中的虚拟机如果关机不当会导致整个虚拟机坏掉,而且采用各种debug方式都难以让它重新启动.这时你只能用之前备份的各个VDI文件来恢复系统了.还有另一种场 ...

  8. windows的消息传递--消息盒子(超详细EM_UNDO等消息)

    使用delphi的消息机制可以方便操作后台,其中重要的就是sendmessage()函数.下面讲解一下这个函数 function SendMessage(hWnd: HWND; Msg: UINT;  ...

  9. <context-param>与<init-param>的区别与作用(转)

    <context-param>的作用:web.xml的配置中<context-param>配置作用1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件we ...

  10. iPhone5C三大看点:性能不输iPhone5 或售3399元

    乐杨俊编辑修改转载: iPhone 5C的发售时间或最早在9月18日,抢在中秋节前:最迟至国庆十一假期期间. [IT商业新闻网综合讯](记者 林涛)苹果2013年秋季发布会还有几个小时即将开幕,除了i ...