You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin Forms中获取视频时长?

获取Xamarin中视频时长的实现方案

嘿,既然你已经搞定了视频缩略图的生成,那获取视频时长其实也是原生API就能搞定的事儿,咱们分Android和iOS两个平台来具体说:

Android平台实现

Android可以用MediaMetadataRetriever类提取视频元数据,其中就包含时长信息,代码示例如下:

using Android.Media;

public static long GetVideoDuration(string videoFilePath)
{
    // 使用using确保资源被正确释放
    using (var metadataRetriever = new MediaMetadataRetriever())
    {
        try
        {
            // 设置视频文件路径
            metadataRetriever.SetDataSource(videoFilePath);
            // 提取时长元数据,返回的是毫秒数的字符串
            string durationString = metadataRetriever.ExtractMetadata(MetadataKey.Duration);
            
            if (long.TryParse(durationString, out long durationInMilliseconds))
            {
                // 返回毫秒数,你可以根据需求转成秒、时分秒格式
                return durationInMilliseconds;
            }
        }
        catch (Exception ex)
        {
            // 处理异常,比如文件不存在、无权限等
            Console.WriteLine($"获取视频时长失败:{ex.Message}");
        }
        
        return 0;
    }
}

注意事项

  • 确保你的应用拥有读取视频文件的权限:Android 12及以下需要READ_EXTERNAL_STORAGE权限,Android 13+需要READ_MEDIA_VIDEO权限,记得在AndroidManifest.xml中声明并动态申请权限。
  • 如果视频是网络路径,SetDataSource也支持传入URL,但需要注意网络权限和文件可访问性。

iOS平台实现

iOS则可以借助AVFoundation框架中的AVAsset来获取视频时长,代码示例如下:

using AVFoundation;
using Foundation;
using System.Threading.Tasks;

public static async Task<double> GetVideoDurationAsync(string videoFilePath)
{
    try
    {
        // 通过文件路径创建AVAsset实例
        var videoAsset = AVAsset.FromUrl(NSUrl.FromFilename(videoFilePath));
        // 异步加载时长数据
        var loadStatus = await videoAsset.LoadValuesTaskAsync(new string[] { "duration" });
        
        if (loadStatus == AVKeyValueStatus.Loaded)
        {
            // 将CMTime类型的时长转换成秒数返回
            return videoAsset.Duration.Seconds;
        }
    }
    catch (Exception ex)
    {
        // 处理异常,比如权限不足、文件无效等
        Console.WriteLine($"获取视频时长失败:{ex.Message}");
    }
    
    return 0;
}

注意事项

  • 如果你需要访问相册中的视频,记得在Info.plist中添加NSPhotoLibraryUsageDescription(iOS 10+)权限描述,否则会被系统拒绝访问。
  • AVAsset的加载是异步的,用Task处理更符合iOS的异步编程规范。

Xamarin.Forms跨平台调用

如果你是在Xamarin.Forms项目中使用,可以通过DependencyService统一调用原生实现:

  1. 定义共享接口:
public interface IVideoMetadataService
{
    Task<double> GetVideoDurationAsync(string videoPath);
}
  1. 在Android项目中实现接口:
[assembly: Dependency(typeof(VideoMetadataServiceAndroid))]
namespace YourApp.Droid
{
    public class VideoMetadataServiceAndroid : IVideoMetadataService
    {
        public Task<double> GetVideoDurationAsync(string videoPath)
        {
            long durationMs = GetVideoDuration(videoPath);
            // 转成秒数返回
            return Task.FromResult(durationMs / 1000.0);
        }
        
        // 复用Android平台的时长获取方法
        private long GetVideoDuration(string videoFilePath)
        {
            using (var metadataRetriever = new MediaMetadataRetriever())
            {
                try
                {
                    metadataRetriever.SetDataSource(videoFilePath);
                    string durationString = metadataRetriever.ExtractMetadata(MetadataKey.Duration);
                    
                    if (long.TryParse(durationString, out long durationInMilliseconds))
                    {
                        return durationInMilliseconds;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"获取视频时长失败:{ex.Message}");
                }
                
                return 0;
            }
        }
    }
}
  1. 在iOS项目中实现接口:
[assembly: Dependency(typeof(VideoMetadataServiceiOS))]
namespace YourApp.iOS
{
    public class VideoMetadataServiceiOS : IVideoMetadataService
    {
        public async Task<double> GetVideoDurationAsync(string videoPath)
        {
            return await GetVideoDurationInternalAsync(videoPath);
        }
        
        // 复用iOS平台的时长获取方法
        private async Task<double> GetVideoDurationInternalAsync(string videoFilePath)
        {
            try
            {
                var videoAsset = AVAsset.FromUrl(NSUrl.FromFilename(videoFilePath));
                var loadStatus = await videoAsset.LoadValuesTaskAsync(new string[] { "duration" });
                
                if (loadStatus == AVKeyValueStatus.Loaded)
                {
                    return videoAsset.Duration.Seconds;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取视频时长失败:{ex.Message}");
            }
            
            return 0;
        }
    }
}
  1. 在Forms项目中调用:
var durationInSeconds = await DependencyService.Get<IVideoMetadataService>().GetVideoDurationAsync("你的视频路径");
// 转成友好的时分秒格式
TimeSpan duration = TimeSpan.FromSeconds(durationInSeconds);
string formattedDuration = $"{duration.Hours:D2}:{duration.Minutes:D2}:{duration.Seconds:D2}";

内容的提问来源于stack exchange,提问作者Vernon007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:06:00