• 【作业】too young too simple mediaplayer


    too young too simple mediaplayer


           这是一个简单的播放器,能且只能播放mp3和mp4文件,通过右键菜单选取文件来播放。

           https://github.com/lotsofone/HomeWorkPlayer

           播放效果

           下面分别是播放mp3和mp4的效果。

         


           文件读取

           在做这个too-young-too-simple-mediaplayer的时候,遇到的第一个问题就是读取文件的问题。为了避免我随意篡改文件植入病毒盗取密码控制电脑搞DDos攻击,uwp限制了应用对文件的访问,我们无法随意地读取文件。

           读取文件的过程异常复杂,首先要用FileOpenPicker去让用户选择文件,然后要得到StorageFile,然后再打开成IRandomAccessStream,最后终于可以把文件传到MediaElement了。

            用到的网页有:

           https://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/windows.storage.pickers.fileopenpicker.aspx

        这个网页没有有价值的代码,我是通过函数返回值找到下一个类,再通过下一个类的返回值一层层找,找到了前文提到的“链条”。

           https://docs.microsoft.com/en-us/previous-versions/windows/apps/hh771180(v=win.10)

        这个网页提供了如下代码:

    FileOpenPicker openPicker = new FileOpenPicker();
    openPicker.ViewMode = PickerViewMode.Thumbnail;
    openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
    openPicker.FileTypeFilter.Add(".jpg");
    openPicker.FileTypeFilter.Add(".jpeg");
    openPicker.FileTypeFilter.Add(".png");
    
    StorageFile file = await openPicker.PickSingleFileAsync();
    if (file != null)
    {
        // Application now has read/write access to the picked file
        OutputTextBlock.Text = "Picked photo: " + file.Name;
    }
    else
    {
        OutputTextBlock.Text = "Operation cancelled.";
    }
    View Code

        然后我就写出来了:

                FileOpenPicker picker = new FileOpenPicker();
                picker.ViewMode = PickerViewMode.Thumbnail;
    
                picker.FileTypeFilter.Add(".mp4");
                picker.FileTypeFilter.Add(".mp3");
                StorageFile file = await picker.PickSingleFileAsync();
    
                if (file != null)
                {
                    var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
                    mainplayer.SetSource(stream, file.ContentType);
                    musicpic.Opacity = 100;
                }
    View Code

           右键菜单

           然后是右键菜单打开文件。本来最简单的办法是用一个Button去触发一个事件,然后开启FileOpenPicker,然后去弄上面一长串的东西。然而,加一个Button对这个界面太不友好了,看起来十分不美观。一整片的东西旁边挂一个小按钮,然后还挡住看视频,成何体统,所以就想用右键打开Flyout来选取文件。

            比较容易处理的Flyout是Button.Flyout,按一下按钮打开Flyout。但是之前就说了弄个按钮很丑,所以这个方案否决,于是就找到了用FlyoutBase,然后通过右键事件来让这个Flyout弹出来的办法。不过呢,这个办法弹出的Flyout时钟出现在窗体最上方,无法做到在右键处出现Flyout起到右键菜单的效果,所以又是搜啊搜。

           终于又找到了另外一种方法,这种方法里面其实MenuFlyout已经独立于这个MediaElement了。它相当于是个Flyout的模板,通过x:Name才能访问到。然后再单独ShowAt在取得的鼠标位置上即可。

           实验中还发现,FlyoutBase和MenuFlyout无法指定Name,只能指定x:Name。

      用到的网页有:

           https://www.cnblogs.com/ansen312/p/5913372.html

        这个网页写了代码:

                <TextBlock Name="textBlock1" Margin="5" Text="按我弹出 Flyout" Tapped="textBlock1_Tapped" FontSize="18">
                    <FlyoutBase.AttachedFlyout>
                        <Flyout Placement="Right">
                            <TextBlock Text="我是 Flyout 中的内容" />
                        </Flyout>
                    </FlyoutBase.AttachedFlyout>
                </TextBlock>
    View Code

        然后我猜想FlyoutBase.AttachedFlyout是不是能写在任何东西里面,就试了下放进MediaElement,结果还真可以:

           <MediaElement Name="mainplayer"  HorizontalAlignment="Left" Height="auto" VerticalAlignment="Top" Width="auto" AutoPlay="True"
    AreTransportControlsEnabled="True" RightTapped="mainplayer_RightTapped">
                <FlyoutBase.AttachedFlyout>
                    <MenuFlyout x:Name="mainmenu">
                        <MenuFlyoutItem Text="选择文件" Tag="选择文件" Click="Button_ClickAsync"/>
                    </MenuFlyout>
                </FlyoutBase.AttachedFlyout>
            </MediaElement>
    View Code

           https://blog.csdn.net/lindexi_gd/article/details/52724410

        这个网页里面写了:

       private void GridColection_OnRightTapped(object sender, RightTappedRoutedEventArgs e)
    
        {
    
            MenuFlyout myFlyout = new MenuFlyout();
    
            MenuFlyoutItem firstItem = new MenuFlyoutItem { Text = "OneIt" };
    
            MenuFlyoutItem secondItem = new MenuFlyoutItem { Text = "TwoIt" };
    
            myFlyout.Items.Add(firstItem);
    
            myFlyout.Items.Add(secondItem);
    
            //if you only want to show in left or buttom 
    
            //myFlyout.Placement = FlyoutPlacementMode.Left;
    
    
    
            FrameworkElement senderElement = sender as FrameworkElement;
    
            //the code can show the flyout in your mouse click 
    
            myFlyout.ShowAt(sender as UIElement, e.GetPosition(sender as UIElement));
    
        }
    View Code

        其实就是暗示了我,这个FlyoutBase已经超越了MediaElement的管辖,可以独立出现,然后我就写出了:

                mainmenu.ShowAt(sender as UIElement, e.GetPosition(sender as UIElement));
    View Code

           背景切换

           播放音频时会出现音乐背景图片,这个就太简单了,没啥好说的。第一次选择文件的时候把图片背景的Opacity设置成100,然后如果MediaElement打开的是视频,边框就会被黑色填满,否则自己就会变透明。

  • 相关阅读:
    gvim e303 无法打开 “[未命名]“的交换文件,恢复将不可能
    AspectJ获取方法注解的信息
    type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds int,java.lang.Object
    MySQL@淘宝 资料分享
    MySQL的语句执行顺序
    关于HttpClient上传中文乱码的解决办法
    使用IntelliJ IDEA查看类的继承关系图形
    javax.net.ssl.SSLException: Certificate doesn't match any of the subject alternative names
    Failed to process import candidates for configuration class [com.simple.....]
    安装npm及cnpm(Windows)
  • 原文地址:https://www.cnblogs.com/lotsofone/p/8672841.html
Copyright © 2020-2023  润新知