Windows 8 Store Apps学习(65) 后台任务: 音乐的后台播放和控制

介绍

重新想象 Windows 8 Store Apps 之 后台任务

音乐的后台播放和控制

示例

用于保存每首音乐的相关信息的对象

BackgroundTask/SongModel.cs

/*
 * 用于保存每首音乐的相关信息
 */

using System;
using System.Threading.Tasks;
using Windows.Storage;

namespace XamlDemo.BackgroundTask
{
    public class SongModel
    {
        /// <summary>
        /// 音乐文件
        /// </summary>
        public StorageFile File;

        /// <summary>
        /// 艺术家
        /// </summary>
        public string Artist;

        /// <summary>
        /// 音乐名称
        /// </summary>
        public string Title;

        public SongModel(StorageFile file)
        {
            File = file;
        }

        /// <summary>
        /// 加载音乐的相关属性
        /// </summary>
        public async Task LoadMusicPropertiesAsync()
        {
            var properties = await this.File.Properties.GetMusicPropertiesAsync();

            Artist = properties.Artist;
            Title = properties.Title;
        }
    }
}

演示如何通过 MediaControl 实现音乐的后台播放和控制

BackgroundTask/MediaControlDemo.xaml

<Page
    x:Class="XamlDemo.BackgroundTask.MediaControlDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.BackgroundTask"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667"  />

            <Button Name="btnSelectFiles" Content="Select Files" Click="btnSelectFiles_Click" Margin="0 10 0 0"  />
            <Button Name="btnPlay" Content="Play" Click="btnPlay_Click" Margin="0 10 0 0"  />

            <!--
                为了使音乐可以后台播放,需要将 MediaElement 的 AudioCategory 属性设置为 BackgroundCapableMedia
            -->
            <MediaElement Name="mediaElement" AudioCategory="BackgroundCapableMedia" AutoPlay="False"
                          MediaOpened="mediaElement_MediaOpened" MediaEnded="mediaElement_MediaEnded" CurrentStateChanged="mediaElement_CurrentStateChanged"  />

        </StackPanel>
    </Grid>

</Page>

BackgroundTask/MediaControlDemo.cs

/*
 * 演示如何通过 MediaControl 实现音乐的后台播放和控制
 *
 * 注:
 * 1、需要在 Package.appxmanifest 中增加后台任务声明,并勾选“音频”
 * 2、需要将 MediaElement 的 AudioCategory 属性设置为 BackgroundCapableMedia
 *
 * 另:
 * 按下平板上的音量键或者多媒体键盘上的相关按键,会弹出后台音频的控制框,通过 MediaControl 来监听用户在此音频控制框上的操作
 */

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Media;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace XamlDemo.BackgroundTask
{
    public sealed partial class MediaControlDemo : Page
    {
        private List<SongModel> _playList = new List<SongModel>(); // 后台需要播放的音乐列表
        private int _currentSongIndex = 0; // 当前播放的音乐

        private bool _previousTrackPressedRegistered = false; // MediaControl 是否注册了 PreviousTrackPressed 事件
        private bool _nextTrackPressedRegistered = false; // MediaControl 是否注册了 NextTrackPressed 事件

        public MediaControlDemo()
        {
            this.InitializeComponent();

            MediaControl.PlayPauseTogglePressed += MediaControl_PlayPauseTogglePressed; // 按下了 play/pause 键
            MediaControl.PlayPressed += MediaControl_PlayPressed; // 按下了 play 键
            MediaControl.PausePressed += MediaControl_PausePressed; // 按下了 pause 键
            MediaControl.StopPressed += MediaControl_StopPressed; // 按下了 stop 键

            MediaControl.PreviousTrackPressed += MediaControl_PreviousTrackPressed; // 按下了“上一首”键
            MediaControl.NextTrackPressed += MediaControl_NextTrackPressed; // 按下了“下一首”键
            MediaControl.RewindPressed += MediaControl_RewindPressed; // 按下了“快退”键
            MediaControl.FastForwardPressed += MediaControl_FastForwardPressed; // 按下了“快进”键

            MediaControl.SoundLevelChanged += MediaControl_SoundLevelChanged; // 音量级别发生了改变

            // MediaControl.RecordPressed += MediaControl_RecordPressed;
            // MediaControl.ChannelDownPressed += MediaControl_ChannelDownPressed;
            // MediaControl.ChannelUpPressed += MediaControl_ChannelUpPressed;

            // MediaControl.ArtistName; // 当前播放的音乐的艺术家
            // MediaControl.TrackName; // 当前播放的音乐的名称
            // MediaControl.AlbumArt; // 当前播放的音乐的专辑封面的路径
            // MediaControl.IsPlaying; // 当前音乐是否正在播放
            // MediaControl.SoundLevel; // 当前播放的音乐的音量级别(Muted, Low, Full)

             _previousTrackPressedRegistered = true;
             _nextTrackPressedRegistered = true;
        }

        // 按下了音频控制框上的 play/pause 键
        async void MediaControl_PlayPauseTogglePressed(object sender, object e)
        {
            if (MediaControl.IsPlaying)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    mediaElement.Pause();
                });
                await OutputMessage("Play/Pause Pressed - Pause");
            }
            else
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    mediaElement.Play();
                });
                await OutputMessage("Play/Pause Pressed - Play");
            }
        }

        // 按下了音频控制框上的 play 键
        async void MediaControl_PlayPressed(object sender, object e)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                mediaElement.Play();
            });
            await OutputMessage("Play Pressed");
        }

        // 按下了音频控制框上的 pause 键
        async void MediaControl_PausePressed(object sender, object e)
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                mediaElement.Pause();
            });
            await OutputMessage("Pause Pressed");
        }

        // 按下了音频控制框上的 stop 键
        async void MediaControl_StopPressed(object sender, object e)
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                mediaElement.Stop();
            });
            await OutputMessage("Stop Pressed");
        }

        // 按下了音频控制框上的“上一首”键
        async void MediaControl_PreviousTrackPressed(object sender, object e)
        {
            await OutputMessage("Previous Track Pressed");

            if (_currentSongIndex > 0)
            {
                if (_currentSongIndex == (_playList.Count - 1))
                {
                    if (!_nextTrackPressedRegistered)
                    {
                        MediaControl.NextTrackPressed += MediaControl_NextTrackPressed;
                        _nextTrackPressedRegistered = true;
                    }
                }

                _currentSongIndex--;

                if (_currentSongIndex == 0)
                {
                    MediaControl.PreviousTrackPressed -= MediaControl_PreviousTrackPressed;
                    _nextTrackPressedRegistered = false;
                }

                await SetCurrentPlayingAsync(_currentSongIndex);
            }

        }

        // 按下了音频控制框上的“下一首”键
        async void MediaControl_NextTrackPressed(object sender, object e)
        {
            await OutputMessage("Next Track Pressed");

            if (_currentSongIndex < (_playList.Count - 1))
            {
                _currentSongIndex++;
                await SetCurrentPlayingAsync(_currentSongIndex);

                if (_currentSongIndex > 0)
                {
                    if (!_previousTrackPressedRegistered)
                    {
                        MediaControl.PreviousTrackPressed += MediaControl_PreviousTrackPressed;
                        _previousTrackPressedRegistered = true;
                    }

                }

                if (_currentSongIndex == (_playList.Count - 1))
                {
                    if (_nextTrackPressedRegistered)
                    {
                        MediaControl.NextTrackPressed -= MediaControl_NextTrackPressed;
                        _nextTrackPressedRegistered = false;
                    }
                }
            }
        }

        // 按下了音频控制框上的“快退”键,即长按“上一首”键
        async void MediaControl_RewindPressed(object sender, object e)
        {
            await OutputMessage("Rewind Pressed");
        }

        // 按下了音频控制框上的“快进”键,即长按“下一首”键
        async void MediaControl_FastForwardPressed(object sender, object e)
        {
            await OutputMessage("Fast Forward Pressed");
        }

        // 音量级别发生变化时(Muted, Low, Full)
        async void MediaControl_SoundLevelChanged(object sender, object e)
        {
            await OutputMessage("Sound Level Changed");
        }

        // 创建一个需要在后台播放的音乐列表
        private async void btnSelectFiles_Click(object sender, RoutedEventArgs e)
        {
            FileOpenPicker openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.List;
            openPicker.SuggestedStartLocation = PickerLocationId.MusicLibrary;
            openPicker.FileTypeFilter.Add(".mp3");
            openPicker.FileTypeFilter.Add(".wma");
            IReadOnlyList<StorageFile> files = await openPicker.PickMultipleFilesAsync();
            if (files.Count > 0)
            {
                await CreatePlaylist(files);
                await SetCurrentPlayingAsync(_currentSongIndex);
            }
        }

        // 开始播放
        private async void btnPlay_Click(object sender, RoutedEventArgs e)
        {
            if (MediaControl.IsPlaying)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    mediaElement.Pause();
                });
                await OutputMessage("Play/Pause Pressed - Pause");
            }
            else
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    mediaElement.Play();
                });
                await OutputMessage("Play/Pause Pressed - Play");
            }
        }

        // MediaElement 打开文件后,如果需要播放则立刻播放
        private void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
        {
            if (MediaControl.IsPlaying)
            {
                mediaElement.Play();
            }
        }

        // 当前音乐播放完后,转到下一首
        private async void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
        {
            if (_currentSongIndex < _playList.Count - 1)
            {
                _currentSongIndex++;

                await SetCurrentPlayingAsync(_currentSongIndex);

                if (MediaControl.IsPlaying)
                {
                    mediaElement.Play();
                }
            }
        }

        // 根据前台的操作,设置 MediaControl 的 IsPlaying 属性
		// 查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/net/
        private void mediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
        {
            if (mediaElement.CurrentState == MediaElementState.Playing)
            {
                MediaControl.IsPlaying = true;
                btnPlay.Content = "Pause";
            }
            else
            {
                MediaControl.IsPlaying = false;
                btnPlay.Content = "Play";
            }
        }

        // 创建音乐列表
        private async Task CreatePlaylist(IReadOnlyList<StorageFile> files)
        {
            if (_previousTrackPressedRegistered)
            {
                MediaControl.PreviousTrackPressed -= MediaControl_PreviousTrackPressed;
                _previousTrackPressedRegistered = false;
            }
            if (_nextTrackPressedRegistered)
            {
                MediaControl.NextTrackPressed -= MediaControl_NextTrackPressed;
                _nextTrackPressedRegistered = false;
            }

            _playList.Clear();
            _currentSongIndex = 0;

            if (files.Count > 0)
            {
                if (files.Count > 1)
                {
                    MediaControl.NextTrackPressed += MediaControl_NextTrackPressed;
                    _nextTrackPressedRegistered = true;
                }

                foreach (StorageFile file in files)
                {
                    SongModel song = new SongModel(file);
                    await song.LoadMusicPropertiesAsync();
                    _playList.Add(song);
                }
            }
        }

        // 指定当前需要播放的音乐
        private async Task SetCurrentPlayingAsync(int playListIndex)
        {
            string errorMessage = null;
            IRandomAccessStream stream = null;

            try
            {
                stream = await _playList[playListIndex].File.OpenAsync(Windows.Storage.FileAccessMode.Read);
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    mediaElement.SetSource(stream, _playList[playListIndex].File.ContentType);
                });
            }
            catch (Exception e)
            {
                errorMessage = e.Message;
            }

            if (errorMessage != null)
            {
                await OutputMessage(errorMessage);
            }

            MediaControl.ArtistName = _playList[playListIndex].Artist;
            MediaControl.TrackName = _playList[playListIndex].Title;
        }

        // 输出信息
        private async Task OutputMessage(string message)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                lblMsg.Text = message + ": " + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            });
        }
    }
}

OK

源码下载:http://files.cnblogs.com/webabcd/Windows8.rar

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索windows
, object
, 音乐
, task await delay
, await
, mediacontroller
, ynamic ata isplay
, 后台file为null
, MediaElement
, 后台播放
async属性
,以便于您获取更多的相关知识。

时间: 2024-09-23 17:19:26

Windows 8 Store Apps学习(65) 后台任务: 音乐的后台播放和控制的相关文章

重新想象 Windows 8 Store Apps (65) - 后台任务: 音乐的后台播放和控制

原文:重新想象 Windows 8 Store Apps (65) - 后台任务: 音乐的后台播放和控制 [源码下载] 重新想象 Windows 8 Store Apps (65) - 后台任务: 音乐的后台播放和控制 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后台任务 音乐的后台播放和控制 示例用于保存每首音乐的相关信息的对象BackgroundTask/SongModel.cs /* * 用于保存每首音乐的相关信息 */ using System; u

Windows 8 Store Apps学习(68) 后台任务:控制通道(ControlChannel)

介绍 重新想象 Windows 8 Store Apps 之 后台任务 控制通道(ControlChannel) 示例 1.客户端与服务端做 ControlChannel 通信的关键代码 ControlChannelHelper/AppContext.cs /* * 本例通过全局静态变量来实现 app 与 task 的信息共享,以便后台任务可以获取到 app 中的相关信息 * * 注: * 也可以通过 Windows.ApplicationModel.Core.CoreApplication.P

Windows 8 Store Apps学习(67) 后台任务: 推送通知

介绍 重新想象 Windows 8 Store Apps 之 后台任务 推送通知 示例 1.客户端 BackgroundTask/PushNotification.xaml <Page x:Class="XamlDemo.BackgroundTask.PushNotification" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://s

Windows 8 Store Apps学习(66) 后台任务: 下载和上传

介绍 重新想象 Windows 8 Store Apps 之 后台任务 后台下载任务 后台上传任务 示例 扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知 BackgroundTask/TransferModel.cs /* * 扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知 */ using System; using System.ComponentModel; usin

Windows 8 Store Apps学习(64) 后台任务: 开发一个简单的后台任务

介绍 重新想象 Windows 8 Store Apps 之 后台任务 开发一个简单的后台任务 示例 1.通过"Windows 运行时组件"新建一个后台任务 BackgroundTaskLib/Demo.cs /* * 后台任务 * * 注: * 后台任务项目的输出类型需要设置为"Windows 运行时组件",其会生成 .winmd 文件,winmd - Windows Metadata */ using System; using System.Threading

Windows 8 Store Apps学习(41) 打印

介绍 重新想象 Windows 8 Store Apps 之 打印 示例 1.需要打印的文档 Print/PrintPage.xaml <Page x:Class="XamlDemo.Print.PrintPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xam

Windows 8 Store Apps学习(59) 锁屏

介绍 重新想象 Windows 8 Store Apps 之 锁屏 登录锁屏,获取当前程序的锁屏权限,从锁屏中移除 发送徽章或文本到锁屏 将一个 app 的多个 tile 绑定到锁屏 自定义锁屏图片 示例 1.演示如何登录锁屏,获取当前程序的锁屏权限,从锁屏中移除 LockScreen/AccessLockScreen.xaml <Page x:Class="XamlDemo.LockScreen.AccessLockScreen" xmlns="http://sche

Windows 8 Store Apps学习(55) 绑定: MVVM 模式

介绍 重新想象 Windows 8 Store Apps 之 绑定 通过 MVVM 模式实现数据的添 加.删除.修改和查询 示例 1.Model 层 Binding/MVVM/Model/ProductDatabase.cs /* * Model 层的数据持久化操作(本地或远程) * * 本例只是一个演示 */ using System; using System.Collections.Generic; using System.Linq; namespace XamlDemo.Binding

Windows 8 Store Apps学习(21) 动画: ThemeTransition(过渡效果)

介绍 重新想象 Windows 8 Store Apps 之 动画 ThemeTransition 的概述 EntranceThemeTransition - 页面间跳转时的过渡效果 ContentThemeTransition - 内容改变时的过渡效果 RepositionThemeTransition - 位置改变时的过渡效果 PopupThemeTransition - 弹出时的过渡效果 AddDeleteThemeTransition - 添加项或删除项时的过渡效果 ReorderThe