我正在Xamarin Forms应用程序中实现视频播放器,就像Xamarin提供的视频播放器示例一样
我可以从手机库中选择一个视频,将视频播放器源设置为所选视频,然后播放该视频。如何获取所选视频的实际流或字节,以便将其上传到Blob存储?
我尝试过
使用(FileStream fs = new FileStream(fileName,FileMode.Open,FileAccess.Read))..........
其中fileName是设置为视频播放器源的所选视频的路径和文件名。由于找不到Android文件名字符串,因此无法使用。 (从xamarin形式调用时)。我意识到即使在iOS上,文件名也会有所不同。如何深入了解平台特定的实现并获取文件字节或所选文件的流? 谢谢
答案 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);
或者,更改该代码以适合您的要求。如果给定的文件路径包含完全限定的位置,请删除逻辑以完全添加文件夹。
这里希望对您有用。