Xamarin表示视频播放器示例 - 获取用于上传的视频字节

问题描述 投票:0回答:2

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

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

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

我试过了

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

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

xamarin xamarin.forms
2个回答
0
投票

您可以通过使用DependencyService简单地完成此操作。您需要调整以下代码以满足您正在使用的文件夹位置,但请执行此操作。

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

在您的共享项目中添加一个名为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);

或者,更改该代码以满足您的要求。如果您获得的文件路径包含完全限定的位置,则删除逻辑以完全添加该文件夹。

这里希望对你有用。


1
投票

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

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

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

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

这应该让你开始,但肯定会有很多警告。例如,如果您尝试在捕获要在某处上传的字节时播放视频,则必须遵守非常紧凑的时间范围。如果您花费太长时间来处理流,则会降低播放速度并降低用户体验。


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

例如,以下代码:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.