Xamarin 视频播放器无法播放模拟器文档文件夹中的视频 [英] Xamarin video player unable to play video from simulator document folder

查看:34
本文介绍了Xamarin 视频播放器无法播放模拟器文档文件夹中的视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现了 xamarin 视频播放器,其描述如下链接 https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/video-player/

Hi i implemented the xamarin video player which is described the following link https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/video-player/

我正在通过代码将视频下载到具有这样路径的应用程序的文档文件夹中[/Users/vaibhavjain/Library/Developer/CoreSimulator/Devices/{GUID}/data/Containers/Data/Application/{GUID}/Documents/MediaDocuments/Nature1.mp4]现在我检查了视频是否正确下载到此路径,但是当我将此路径作为源传递给上面的视频播放器时,它无法播放

i am downloading videos through code to the documents folder of the application which has a path like this [/Users/vaibhavjain/Library/Developer/CoreSimulator/Devices/{GUID}/data/Containers/Data/Application/{GUID}/Documents/MediaDocuments/Nature1.mp4] now i checked that videos are downloaded correctly to this path but when i am passing this path as source to the video player above it is not able to play it

我的猜测是玩家无法到达路径或者它期待相对路径,但我无法找到我应该提供的路径类型的任何示例.

my guess is that the player is not able to reach the path or it is expecting a relative path but i am unable to find any example of the type of path i should provide.

这里是ios上自定义Renderer的代码

here is the code for custom Renderer on ios

public class VideoPlayerRenderer : ViewRenderer<VideoPlayer, UIView>
{
    AVPlayer player;
    AVPlayerItem playerItem;
    AVPlayerViewController _playerViewController;       // solely for ViewController property

    public override UIViewController ViewController => _playerViewController;

    protected override void OnElementChanged(ElementChangedEventArgs<VideoPlayer> args)
    {
        base.OnElementChanged(args);

        if (args.NewElement != null)
        {
            if (Control == null)
            {
                // Create AVPlayerViewController
                _playerViewController = new AVPlayerViewController();

                // Set Player property to AVPlayer
                player = new AVPlayer();
                _playerViewController.Player = player;

                var x = _playerViewController.View;

                // Use the View from the controller as the native control
                SetNativeControl(_playerViewController.View);
            }

            SetAreTransportControlsEnabled();
            SetSource();

            args.NewElement.UpdateStatus += OnUpdateStatus;
            args.NewElement.PlayRequested += OnPlayRequested;
            args.NewElement.PauseRequested += OnPauseRequested;
            args.NewElement.StopRequested += OnStopRequested;
        }

        if (args.OldElement != null)
        {
            args.OldElement.UpdateStatus -= OnUpdateStatus;
            args.OldElement.PlayRequested -= OnPlayRequested;
            args.OldElement.PauseRequested -= OnPauseRequested;
            args.OldElement.StopRequested -= OnStopRequested;
        }
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);

        if (player != null)
        {
            player.ReplaceCurrentItemWithPlayerItem(null);
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        base.OnElementPropertyChanged(sender, args);

        if (args.PropertyName == VideoPlayer.AreTransportControlsEnabledProperty.PropertyName)
        {
            SetAreTransportControlsEnabled();
        }
        else if (args.PropertyName == VideoPlayer.SourceProperty.PropertyName)
        {
            SetSource();
        }
        else if (args.PropertyName == VideoPlayer.PositionProperty.PropertyName)
        {
            TimeSpan controlPosition = ConvertTime(player.CurrentTime);

            if (Math.Abs((controlPosition - Element.Position).TotalSeconds) > 1)
            {
                player.Seek(CMTime.FromSeconds(Element.Position.TotalSeconds, 1));
            }
        }
    }

    void SetAreTransportControlsEnabled()
    {
        ((AVPlayerViewController)ViewController).ShowsPlaybackControls = Element.AreTransportControlsEnabled;
    }

    void SetSource()
    {
        AVAsset asset = null;

        if (Element.Source is UriVideoSource)
        {
            string uri = (Element.Source as UriVideoSource).Uri;

            if (!String.IsNullOrWhiteSpace(uri))
            {
                asset = AVAsset.FromUrl(new NSUrl(uri));
            }
        }
        else if (Element.Source is FileVideoSource)
        {
            string uri = (Element.Source as FileVideoSource).File;

            if (!String.IsNullOrWhiteSpace(uri))
            {
                asset = AVAsset.FromUrl(NSUrl.CreateFileUrl(uri, null));
            }
        }
        else if (Element.Source is ResourceVideoSource)
        {
            string path = (Element.Source as ResourceVideoSource).Path;

            if (!String.IsNullOrWhiteSpace(path))
            {
                string directory = Path.GetDirectoryName(path);
                string filename = Path.GetFileNameWithoutExtension(path);
                string extension = Path.GetExtension(path).Substring(1);
                NSUrl url = NSBundle.MainBundle.GetUrlForResource(filename, extension, directory);
                asset = AVAsset.FromUrl(url);
            }
        }

        if (asset != null)
        {
            playerItem = new AVPlayerItem(asset);
        }
        else
        {
            playerItem = null;
        }

        player.ReplaceCurrentItemWithPlayerItem(playerItem);

        if (playerItem != null && Element.AutoPlay)
        {
            player.Play();
        }
    }

    // Event handler to update status
    void OnUpdateStatus(object sender, EventArgs args)
    {
        VideoStatus videoStatus = VideoStatus.NotReady;

        switch (player.Status)
        {
            case AVPlayerStatus.ReadyToPlay:
                switch (player.TimeControlStatus)
                {
                    case AVPlayerTimeControlStatus.Playing:
                        videoStatus = VideoStatus.Playing;
                        break;

                    case AVPlayerTimeControlStatus.Paused:
                        videoStatus = VideoStatus.Paused;
                        break;
                }
                break;
        }
        ((IVideoPlayerController)Element).Status = videoStatus;

        if (playerItem != null)
        {
            ((IVideoPlayerController)Element).Duration = ConvertTime(playerItem.Duration);
            ((IElementController)Element).SetValueFromRenderer(VideoPlayer.PositionProperty, ConvertTime(playerItem.CurrentTime));
        }
    }

    TimeSpan ConvertTime(CMTime cmTime)
    {
        return TimeSpan.FromSeconds(Double.IsNaN(cmTime.Seconds) ? 0 : cmTime.Seconds);

    }

    // Event handlers to implement methods
    void OnPlayRequested(object sender, EventArgs args)
    {
        player.Play();
    }

    void OnPauseRequested(object sender, EventArgs args)
    {
        player.Pause();
    }

    void OnStopRequested(object sender, EventArgs args)
    {
        player.Pause();
        player.Seek(new CMTime(0, 1));
    }
}

推荐答案

我没有看到你的代码,不知道你的问题是什么.我将向您展示如何播放存储在文档文件夹中的本地视频:

I don't see your code and can't know what is your problem. I would show you how to make it work about play a local video stored in the document folder:

xamarin.forms 中:

public class MyVideoView : View
{
}

xaml 中,只需使用这个 MyVideoView :

And in xaml, simply use this MyVideoView :

<StackLayout>
    <!-- Place new controls here -->
    <local:MyVideoView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />

</StackLayout>

在iOS项目中,自定义渲染器应该是:

In the iOS project, the custom renderer should be:

public class VideoPlayerRenderer : ViewRenderer
{
    AVPlayer player;
    AVPlayerItem playerItem;
    AVPlayerViewController _playerViewController;       // solely for ViewController property

    public override UIViewController ViewController => _playerViewController;


    protected override void OnElementChanged(ElementChangedEventArgs<View> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            if (Control == null)
            {
                // Create AVPlayerViewController
                _playerViewController = new AVPlayerViewController();

                var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                var path = Path.Combine(documents, "iOSApiVideo.mp4");

                NSUrl url = NSUrl.CreateFileUrl(path, null);

                //if you put your video in the project directly use below code
                //NSUrl url = NSBundle.MainBundle.GetUrlForResource("iOSApiVideo", "mp4");

                // Set Player property to AVPlayer
                player = new AVPlayer(url);

                _playerViewController.Player = player;

                // Use the View from the controller as the native control
                SetNativeControl(_playerViewController.View);

                player.Play();
            }                
        }
    }     
}

path 替换为 your own path 就可以了.

Replace the path with your own path there and it will work.

注意:

不起作用

NSUrl url = new NSUrl(path);

工作

NSUrl url = NSUrl.CreateFileUrl(path, null);

这篇关于Xamarin 视频播放器无法播放模拟器文档文件夹中的视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆