当前位置: 首页 > 知识库问答 >
问题:

Xamarin iOS AvPlayer不播放“application/x-www-form-urlencoded”类型的视频

钱渊
2023-03-14

我想在Xamarin用AvPlayer播放视频。网间网操作系统。我在Firebase存储公司工作。如果我从android上传视频,媒体类型设置为mp4,但从iOS上传视频,媒体类型设置为URLCoded。我可以用AvPlayer播放mp4文件,但URL编码的文件不可播放。另一方面,URL编码的文件可以在android VideoView中播放。你知道这件事吗?

这里是我的代码,首先从多媒体资料中选择视频:

    private async void PickVideoButton_TouchUpInside(object sender, EventArgs e)
    {
        await CrossMedia.Current.Initialize();

        if (!CrossMedia.Current.IsPickVideoSupported)
        {
            return;
        }
        try
        {
            file = await CrossMedia.Current.PickVideoAsync();
            if (file == null)
            {
                return;
            }

            fileStream = await ConvertMovToMp4();
            mediaType = "Video";

            avp = new AVPlayer(NSUrl.FromFilename(file.Path));
            avpvc = new AVPlayerViewController();
            avpvc.Player = avp;
            AddChildViewController(avpvc);
            GeneralPostingStoryViewBackground.AddSubview(avpvc.View);
            avpvc.View.Frame = GeneralPostingStoryImageView.Frame;
            avpvc.ShowsPlaybackControls = true;
            avp.Play();
        }
        catch (Exception ex)
        {
            alert = UIAlertController.Create("Error", "Gallery doesn't support", UIAlertControllerStyle.Alert);
            alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
            PresentViewController(alert, true, null);
        }
    }

    public async Task<Stream> ConvertMovToMp4()
    {
        string exportPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        string exportFilePath = Path.Combine(exportPath, DateTime.Now.ToString() + ".mp4");

        var asset = AVAsset.FromUrl(NSUrl.FromFilename(file.Path));
        var length = asset.Duration.Seconds;
        lengthDuration = Convert.ToInt32(length).ToString();
        AVAssetExportSession export = new AVAssetExportSession(asset, AVAssetExportSession.PresetMediumQuality);
        export.OutputUrl = NSUrl.FromFilename(exportFilePath);
        export.OutputFileType = AVFileType.Mpeg4;
        export.ShouldOptimizeForNetworkUse = true;
        await export.ExportTaskAsync();
        var stream = File.OpenRead(exportFilePath);

        return stream;
    }

然后,将视频上载到firebase存储:

    private async void ShareButton_TouchUpInside(object sender, EventArgs e)
    {
        try
        {
            var result = await PortableSharediOS(ID, mediaType, fileStream, commentText);
            if (result == "Success.")
            {
                CommonValues.viewControllerIndexList.RemoveAt(CommonValues.viewControllerIndexList.Count - 1);
                NavigateViewController();
            }
            else
            {
                alert = UIAlertController.Create("Error", result.ToString(), UIAlertControllerStyle.Alert);
                alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
                PresentViewController(alert, true, null);
            }
        }
        catch (Exception ex)
        {
            alert = UIAlertController.Create("Error", "Check your internet connection.", UIAlertControllerStyle.Alert);
            alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
            PresentViewController(alert, true, null);
        }
    }

最后,我尝试播放视频,正如我所说的,我从android上传的mp4文件是可播放的,但我从iOS上传的文件,avplayer不会播放它们

    public async Task GetStory(int storyIndex)
    {
        var mediaType = stories[storyIndex].StoryType;
        var story = stories[storyIndex];
        user = await firebaseHelper.GetUser(story.StoryOwner);
        if (mediaType == "Photo")
        {
            GetImage(story.MediaLink, storyViewStoryImageView);
            GetImage(user.PhotoLink, storyViewImageView);
            storyViewUserName.Text = user.UserName;
            storyViewContentView.Text = story.Content;
            time = story.MediaDuration;
            storyViewDuration.Text = time.ToString();
        }
        else
        {
            storyViewUserName.Text = user.UserName;
            storyViewContentView.Text = story.Content;
            time = story.MediaDuration;
            var asset = AVAsset.FromUrl(NSUrl.FromString(story.MediaLink));
            var item = AVPlayerItem.FromAsset(asset);
            avp = new AVPlayer(item);
            avp.Muted = false;
            avpvc = new AVPlayerViewController();
            avpvc.Player = avp;
            AddChildViewController(avpvc);
            storyViewStoryImageView.AddSubview(avpvc.View);
            avpvc.View.Hidden = false;
            avpvc.View.Frame = storyViewStoryImageView.Frame;
            avpvc.ShowsPlaybackControls = false;
            avp.Play();
            storyViewDuration.Text = time.ToString();
        }
        timer.Enabled = false;
        timer.Close();
        TimerTextVoid();
    }

我可以在Android上播放所有文件。不管它们是从哪里上传的。

共有1个答案

令狐凌
2023-03-14

我解决了我的问题。从Firebase存储下载文件并保存到设备。然后将其分配给AVAsset。代码:

    public async Task GetStory(int storyIndex)
    {
        var mediaType = stories[storyIndex].StoryType;
        var story = stories[storyIndex];
        user = await firebaseHelper.GetUser(story.StoryOwner);
        if (mediaType == "Photo")
        {
            GetImage(story.MediaLink, storyViewStoryImageView);
            GetImage(user.PhotoLink, storyViewImageView);
            storyViewUserName.Text = user.UserName;
            storyViewContentView.Text = story.Content;
            time = story.MediaDuration;
            storyViewDuration.Text = time.ToString();
        }
        else
        {
            storyViewUserName.Text = user.UserName;
            storyViewContentView.Text = story.Content;
            time = story.MediaDuration;
            var asset = await GetVideo(story.MediaLink);
            var item = new AVPlayerItem(asset);
            avp = new AVPlayer(item);
            avp.Muted = false;
            avpvc = new AVPlayerViewController();
            avpvc.Player = avp;
            AddChildViewController(avpvc);
            storyViewStoryImageView.AddSubview(avpvc.View);
            avpvc.View.Hidden = false;
            avpvc.View.Frame = storyViewStoryImageView.Frame;
            avpvc.ShowsPlaybackControls = false;
            avp.Play();
            storyViewDuration.Text = time.ToString();
        }
        timer.Enabled = false;
        timer.Close();
        TimerTextVoid();
    }

    public async Task<AVAsset> GetVideo(string url)
    {
        string videoFile;
        using (var client = new WebClient())
        {
            var content = client.DownloadData(url);
            var stream = new MemoryStream(content);

            string folder = Path.GetTempPath();
            videoFile = Path.Combine(folder, DateTime.Now.ToString() + ".mp4");

            if (!System.IO.File.Exists(videoFile))
            {
                using (FileStream outputStream = System.IO.File.Create(videoFile))
                {
                    await stream.CopyToAsync(outputStream);
                }
            }
            
        }
        var asset = AVUrlAsset.FromUrl(NSUrl.FromFilename(videoFile));
        return asset;
    }
 类似资料: