Xamarin Forms视频播放器示例-获取要上传的视频字节

时间:2019-03-26 21:27:40

标签: xamarin xamarin.forms

我正在Xamarin Forms应用程序中实现视频播放器,就像Xamarin提供的视频播放器示例一样

https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/video-player/

我可以从手机库中选择一个视频,将视频播放器源设置为所选视频,然后播放该视频。如何获取所选视频的实际流或字节,以便将其上传到Blob存储?

我尝试过

使用(FileStream fs = new FileStream(fileName,FileMode.Open,FileAccess.Read))..........

其中fileName是设置为视频播放器源的所选视频的路径和文件名。由于找不到Android文件名字符串,因此无法使用。 (从xamarin形式调用时)。我意识到即使在iOS上,文件名也会有所不同。如何深入了解平台特定的实现并获取文件字节或所选文件的流? 谢谢

2 个答案:

答案 0 :(得分:1)

我将研究libVLCSharp库,该库为libVLC提供跨平台的.NET / Mono绑定。它们为Xamarin.Forms和实现流处理功能最可能需要的功能提供了良好的支持。您要实现的目标并不简单,但应该完全可行。

首先,您应该查看Stream output的文档:

  

流输出是VLC功能的名称,该功能允许将VLC读取的任何流输出到文件或作为网络流,而不是显示它。

相关教程:Stream to memory (smem) tutorial

这应该可以帮助您入门,但是在此过程中肯定会有很多警告。例如,如果您尝试在捕获要上传到某处的字节的同时播放视频,则必须遵守非常严格的时间范围。如果您花费太长时间来处理流,它将减慢播放速度并损害用户体验。


编辑:您可以考虑的另一种选择是直接与libVLC的MediaPlayer类进行交互,如this answer中所述。示例代码使用C ++,但是.NET绑定中的方法名称非常相似。

例如,以下代码:

libvlc_video_set_callbacks(mplayer,
                           lock_frame, unlock_frame,
                           0, user_data);

可以通过调用绑定库中的SetVideoCallbacks(LibVLCVideoLockCb lockCb, LibVLCVideoUnlockCb unlockCb, LibVLCVideoDisplayCb displayCb)方法(如定义的here)来使用libVLCSharp来实现。

答案 1 :(得分:0)

您可以使用DependencyService非常简单地执行此操作。您需要调整以下代码以适应您正在使用的文件夹位置,但是,请执行此操作。

将所有“测试”命名空间更改为您自己的项目。

在共享项目中添加一个名为 IFileSystem 的界面,如下所示...

using System;

namespace Test.Interfaces
{
    public interface IFileSystem
    {
        byte[] GetFileInBytes(string fileName);
    }
}

在每个平台项目中创建一个依赖服务。为此,我仅提供iOS和Android,但正如您将看到的,两者的逻辑本质上是完全相同的,只是名称空间不同...

iOS

using System;
using System.IO;
using Test.Interfaces;
using Test.iOS.DependencyServices;
using Xamarin.Forms;

[assembly: Dependency(typeof(FileSystem))]
namespace Test.iOS.DependencyServices
{
    public class FileSystem : IFileSystem
    {
        public byte[] GetFileInBytes(string fileName)
        {
            var folder = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos);
            fileName = Path.Combine(folder, fileName);
            return File.Exists(fileName) ? File.ReadAllBytes(fileName) : null;
        }
    }
}

Android

using System;
using System.IO;
using Test.Interfaces;
using Test.Droid.DependencyServices;
using Xamarin.Forms;

[assembly: Dependency(typeof(FileSystem))]
namespace Test.Droid.DependencyServices
{
    public class FileSystem : IFileSystem
    {
        public byte[] GetFileInBytes(string fileName)
        {
            var folder = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos);
            fileName = Path.Combine(folder, fileName);
            return File.Exists(fileName) ? File.ReadAllBytes(fileName) : null;
        }
    }
}

...现在可以从共享项目中的任何位置调用它。

var bytes = DependencyService.Get<IFileSystem>().GetFileInBytes("Test.mp4");

这应该对您有用,不过,您需要将文件夹路径调整为每个平台项目的适当位置。本质上,这一行可能需要更改...

var folder = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos);

或者,更改该代码以适合您的要求。如果给定的文件路径包含完全限定的位置,请删除逻辑以完全添加文件夹。

这里希望对您有用。

相关问题