Uwp——NaiveMediaPlayer
一贷揽、整體效果(請原諒我的渣畫質(zhì))
? ? ? ?這是播放mp4文件的時候,mp3文件的話中間就是白板了,太懶了背景就懶得找圖片放了缴饭。最左邊的+按鈕是打開mp3,mp4文件骆莹,play是控制暫停的颗搂,右邊喇叭是調(diào)節(jié)音量的,雖然設計很反人類……(待會兒你就知道了)
? ? ? ?我用的MediaElement幕垦,不如新版的MediaPlayerElement好用丢氢,我還在其它地方的代碼看到過MediaPlayer聲明變量的,最后又給指定成了MediaPlayerElement智嚷,反正就是亂七八糟的卖丸,我還是用最菜的那個吧纺且。說MediaElement菜是因為相比最新的MediaPlayerElement盏道,播放暫停,還有音量Slider控制都集成在里面了载碌,弱雞MediaElement還得自己定義猜嘱,真的是麻煩(關(guān)鍵我還搞不定)
? ? ? ?上述實現(xiàn)了要求的基本功能,播放mp3嫁艇,mp4文件朗伶,雖然奇丑無比。
作業(yè)鏈接:https://github.com/XuweiC/NaiveUwp
二步咪、思路淺談
? ? ? ?看到這個作業(yè)论皆,毫無疑問的不知從何入手,我知道肯定有相關(guān)的類控件干這個事,但是我連它叫什么名字都不知道……所以就去這么搜Uwp--音樂播放器点晴,然后見識了各種神仙的作品感凤。反正我參考過的鏈接太多了,還有很多重樣的粒督,我是放不過來了陪竿,待會兒就幾個技術(shù)問題放一下參考鏈接吧,應該沒有人……就看三兩個鏈接然后完工的吧屠橄,如果真有的話我敬他/她是條漢子族跛。
①為了解決第一個打開文件的問題,我找到了以下傳送門锐墙。
? ? ? ?第一個鏈接:https://www.cnblogs.com/webabcd/archive/2013/01/24/2874156.html
? ? ? ?文中如是說:重新想象 Windows 8 Store Apps (6) - 控件之媒體控件: Image, MediaElement……balabala
? ? ? ?其實我是不糾結(jié)win8 win10什么的了礁哄,一開始反正什么都不懂,看就行了
? ? ? ?代碼如下:
// 播放本地視頻或音頻
private async void btnPickFile_Click_1(object sender, RoutedEventArgs e)
{
FileOpenPicker picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
picker.FileTypeFilter.Add(".wmv");
picker.FileTypeFilter.Add(".mp4");
picker.FileTypeFilter.Add(".mp3");
picker.FileTypeFilter.Add(".wma");
picker.FileTypeFilter.Add(".png");
var file = await picker.PickSingleFileAsync();
if (file != null)
{
var stream = await file.OpenAsync(FileAccessMode.Read);
// 指定需要讓 MediaElement 播放的媒體流
mediaElement.SetSource(stream, file.ContentType);
}
}
// 通過指定一個 url 播放一個網(wǎng)絡視頻
private void btnPlayUrl_Click_1(object sender, RoutedEventArgs e)
{
mediaElement.Source = new Uri("http://media.w3.org/2010/05/sintel/trailer.mp4", UriKind.Absolute);
}
? ? ? ?基于以上代碼溪北,我寫出了:
private async void OpenFileButton_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
picker.FileTypeFilter.Add(".mp4");
picker.FileTypeFilter.Add(".mp3");
var file = await picker.PickSingleFileAsync();
if (file != null)
{
var stream = await file.OpenAsync(FileAccessMode.Read);
// 指定需要讓 MediaElement 播放的媒體流
mediaElement.SetSource(stream, file.ContentType);
}
mediaElement.Play();
}
? ? ? ?對我什么都沒干姐仅,就把文件后綴名改掉了,同時忽視了url播放網(wǎng)絡視頻刻盐,因為添加源就可以了掏膏,我們要Naive一點的,就播放本地視頻吧敦锌。
②為了解決第二個播放控制問題馒疹,我參考了以下鏈接。
? ? ? ?我是真的服氣乙墙!MediaElement真是廢物颖变!好了吐槽完了,我們來說說播放控制吧听想,因為上述過程結(jié)束之后需要一個簡易的播放暫停按鈕啊腥刹,再Naive也得要這個吧!所以我就在這條路上越走越遠汉买,什么音量了衔峰,滑塊了,神煩蛙粘。
第二道傳送門:https://blog.csdn.net/linwh8/article/details/70314698
以及? ? ? ?? ? ? ?? ?https://www.cnblogs.com/tianma3798/p/5928217.html
? ? ? ?第一個鏈接中代碼如下
private void pause_Click(object sender, RoutedEventArgs e)
{
try
{
if (_mediaTimelineController.State == MediaTimelineControllerState.Running)
{
EllStoryboard.Pause();
_mediaTimelineController.Pause();
}
else
{
//EllStoryboard.Resume();
EllStoryboard.Begin();
_mediaTimelineController.Resume();
}
}
catch
{
}
}
private void start_Click(object sender, RoutedEventArgs e)
{
try
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
EllStoryboard.Begin();
_mediaTimelineController.Start();
}
catch {
}
}
? ? ? ?部分變量的解釋我放在這里:
public sealed partial class MainPage : Page
{
MediaPlayer _mediaPlayer = new MediaPlayer();
MediaTimelineController _mediaTimelineController = new MediaTimelineController();
TimeSpan _duration;
// MediaPlaybackSession _mediaPlaybackSession = new MediaPlaybackSession();
public MainPage()
{
this.InitializeComponent();
var mediaSource = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/Video1.MP4"));
mediaSource.OpenOperationCompleted += MediaSource_OpenOperationCompleted;
_mediaPlayer.Source = mediaSource;
_mediaPlayer.CommandManager.IsEnabled = false;
_mediaPlayer.TimelineController = _mediaTimelineController;
//_mediaPlayer.Play();
_mediaPlayerElement.SetMediaPlayer(_mediaPlayer);
}
? ? ? ?所以我理所當然的沒學會垫卤,他用的就是上述我提到的mediaplayer,然后
_mediaPlayerElement.SetMediaPlayer(_mediaPlayer);……不提了不提了出牧,都是淚穴肘。
然后我又找到了第二個鏈接,代碼如下:
private void button_Click(object sender, RoutedEventArgs e)
{
if (button.Content.ToString() == "播放")
{
button.Content = "暫停";
mediaElement.Play();
}
else
{
button.Content = "播放";
mediaElement.Pause();
}
}
? ? ? ?于是就有了我作業(yè)里的:
private void PlayButton_Click(object sender, RoutedEventArgs e)
{
if (PlayButton.Content.ToString() == "Play")
{
PlayButton.Content = "Pause";
mediaElement.Play();
}
else
{
PlayButton.Content = "Play";
mediaElement.Pause();
}
}
? ? ? ?盡管這樣還會有一個小bug舔痕,我測試的時候先點的+打開一個文件评抚,然后按鈕還是Play豹缀,點一下,沒反應慨代,再點一下耿眉,才能暫停,好了這個問題我們先不談了鱼响。(MediaPlayerElement你是真的賴皮)
③音量控制問題
? ? ? ?顯然鸣剪,MediaElement并沒給配音量調(diào)節(jié),所以為了解決這個問題丈积,我第一個想到的是筐骇,我得做一個Slider,通過數(shù)據(jù)綁定讓音量隨滑塊值的變化而變化江滨,而且點擊喇叭之后出現(xiàn)滑塊铛纬,也就是可以用一個flyout。
? ? ? ?理想當然豐滿唬滑,結(jié)果是我做了一個反人類的音量調(diào)節(jié)器……flyout也由于沒有搞定滑塊數(shù)據(jù)綁定而無心再弄告唆,以及被MediaPlayerElement氣得半死。
? ? ? ?我的音量調(diào)節(jié)功能是我自己瞎搗鼓的晶密,代碼如下:
public void Volumn_ValueChanged(object sender, RoutedEventArgs e)
{
}
private void VoiceButton_Click(object sender, RoutedEventArgs e)
{
mediaElement.Volume = Volumn.Value;
//mediaElement.Volume = {Binding value, ElementName=Volumn};
}
? ? ? ?你一眼就能看到我把音量調(diào)節(jié)放在了Click里擒悬,也就是說拖動滑塊,然后點擊那個喇叭稻艰,然后就完成了音量調(diào)節(jié)功能了懂牧,本來這里應該放置靜音功能的。結(jié)果調(diào)節(jié)沒搞成尊勿,然后就成這樣了僧凤。
? ? ? ?以下是我在搜集資料時候參考的部分鏈接: uwp開發(fā):Slider控件和MediaElement綁定,實現(xiàn)拖動播放元扔。
哼躯保,你說為什么沒有Slider&音量控制這個選項?因為MediaPlayerElement已經(jīng)完成這件事了澎语!倒是進度條拖動控制視頻播放進度的東西有一堆途事,用的是一個叫做轉(zhuǎn)換器的東西。
? ? ? ?參考代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace Homework8.Converter
{
class timeLineConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return ((TimeSpan)value).TotalSeconds;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return TimeSpan.FromSeconds((double)value);
}
}
}
? ? ? ?總結(jié):在實現(xiàn)Naive播放器的時候咏连,我遇到的就是以上幾個問題盯孙,MediaPlayerElement選手們,嫉妒使我面目猙獰祟滴。這告訴我們以后要實現(xiàn)什么功能的時候要去找找那些主流的控件/工具,這能省大力氣歌溉!其實一個用戶交互體驗好垄懂,干凈骑晶、功能齊全的音樂播放器還是挺復雜的,這次我對那些控件的使用有了更多的理解草慧,參考官方文檔也能學到很多東西桶蛔,比如:
? ? ? ?https://docs.microsoft.com/zh-cn/windows/uwp/design/controls-and-patterns/media-playback