使用 C# 从 ASP.Net MVC 中的视频文件中获取视频元数据的最佳方法是啥?

Posted

技术标签:

【中文标题】使用 C# 从 ASP.Net MVC 中的视频文件中获取视频元数据的最佳方法是啥?【英文标题】:What's the best way to get video metadata from a video file in ASP.Net MVC using C#?使用 C# 从 ASP.Net MVC 中的视频文件中获取视频元数据的最佳方法是什么? 【发布时间】:2014-11-20 23:25:00 【问题描述】:

我已经在 Google 和 *** 上搜索了好几个小时。 *** 上似乎有很多类似的问题,但都是 3-5 岁左右。

现在使用 FFMPEG 仍然是从 .NET Web 应用程序中的视频文件中提取元数据的最佳方式吗?如果是这样,最好的 C# 包装器是什么?

我已经尝试过 MediaToolkit、MediaFile.dll,但没有任何运气。我看到了 ffmpeg-csharpe,但它看起来好像几年没碰过。

我没有找到关于这个主题的任何当前数据。现在可以从最新版本的 .NET 中内置的视频中提取元数据了吗?

我现在基本上是在寻找任何方向。

我应该补充一点,我使用的任何东西每小时都可以调用数千次,因此它需要高效。

【问题讨论】:

【参考方案1】:

看看MediaInfo项目(http://mediaarea.net/en/MediaInfo)

它获取有关大多数媒体类型的大量信息,并且该库与一个易于使用的 c# 辅助类捆绑在一起。

您可以从这里下载适用于 windows 的库和帮助程序类:

http://mediaarea.net/en/MediaInfo/Download/Windows (没有安装程序的DLL)

帮助类位于Developers\Source\MediaInfoDLL\MediaInfoDLL.cs,只需将其添加到您的项目中并将MediaInfo.dll 复制到您的bin。

用法

您可以通过从库中请求特定参数来获取信息,这里是一个示例:

[STAThread]
static void Main(string[] Args)

    var mi = new MediaInfo();
    mi.Open(@"video path here");

    var videoInfo = new VideoInfo(mi);
    var audioInfo = new AudioInfo(mi);
     mi.Close();


public class VideoInfo 

    public string Codec  get; private set; 
    public int Width  get; private set; 
    public int Heigth  get; private set; 
    public double FrameRate  get; private set; 
    public string FrameRateMode  get; private set; 
    public string ScanType  get; private set; 
    public TimeSpan Duration  get; private set; 
    public int Bitrate  get; private set; 
    public string AspectRatioMode  get; private set; 
    public double AspectRatio  get; private set; 

    public VideoInfo(MediaInfo mi)
    
        Codec=mi.Get(StreamKind.Video, 0, "Format");
        Width = int.Parse(mi.Get(StreamKind.Video, 0, "Width"));
        Heigth = int.Parse(mi.Get(StreamKind.Video, 0, "Height"));
        Duration = TimeSpan.FromMilliseconds(int.Parse(mi.Get(StreamKind.Video, 0, "Duration")));
        Bitrate = int.Parse(mi.Get(StreamKind.Video, 0, "BitRate"));
        AspectRatioMode = mi.Get(StreamKind.Video, 0, "AspectRatio/String"); //as formatted string
        AspectRatio =double.Parse(mi.Get(StreamKind.Video, 0, "AspectRatio"));
        FrameRate = double.Parse(mi.Get(StreamKind.Video, 0, "FrameRate"));
        FrameRateMode = mi.Get(StreamKind.Video, 0, "FrameRate_Mode");
        ScanType = mi.Get(StreamKind.Video, 0, "ScanType");
    


public class AudioInfo

    public string Codec  get; private set; 
    public string CompressionMode  get; private set; 
    public string ChannelPositions  get; private set; 
    public TimeSpan Duration  get; private set; 
    public int Bitrate  get; private set; 
    public string BitrateMode  get; private set; 
    public int SamplingRate  get; private set; 

    public AudioInfo(MediaInfo mi)
    
        Codec = mi.Get(StreamKind.Audio, 0, "Format");
        Duration = TimeSpan.FromMilliseconds(int.Parse(mi.Get(StreamKind.Audio, 0, "Duration")));
        Bitrate = int.Parse(mi.Get(StreamKind.Audio, 0, "BitRate"));
        BitrateMode = mi.Get(StreamKind.Audio, 0, "BitRate_Mode");
        CompressionMode = mi.Get(StreamKind.Audio, 0, "Compression_Mode");
        ChannelPositions = mi.Get(StreamKind.Audio, 0, "ChannelPositions");
        SamplingRate = int.Parse(mi.Get(StreamKind.Audio, 0, "SamplingRate"));
    

您可以通过调用Inform()轻松获取字符串格式的所有信息:

        var mi = new MediaInfo();
        mi.Open(@"video path here");
        Console.WriteLine(mi.Inform());
        mi.Close();

如果您需要有关可用参数的更多信息,您可以通过调用Options("Info_Parameters") 来简单地查询所有参数:

        var mi = new MediaInfo();
        Console.WriteLine(mi.Option("Info_Parameters"));
        mi.Close();

【讨论】:

谢谢。在您的帮助下,我能够让 MediaInfo 在我的解决方案中发挥作用!【参考方案2】:

可能有点晚了... 您可以使用 MediaToolKit 的 NuGet 包以最少的代码完成此操作

欲了解更多信息,请从这里MediaToolKit

【讨论】:

我在使用 MediaInfo 时遇到了问题,这要容易得多。不知道为什么 OP 不想使用它。 好像没有维护【参考方案3】:

我建议你使用ffmpeg和Process.Start,代码如下:

    private string GetVideoDuration(string ffmpegfile, string sourceFile) 
        using (System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process()) 
            String duration;  // soon will hold our video's duration in the form "HH:MM:SS.UU"
            String result;  // temp variable holding a string representation of our video's duration
            StreamReader errorreader;  // StringWriter to hold output from ffmpeg

            // we want to execute the process without opening a shell
            ffmpeg.StartInfo.UseShellExecute = false;
            //ffmpeg.StartInfo.ErrorDialog = false;
            ffmpeg.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            // redirect StandardError so we can parse it
            // for some reason the output comes through over StandardError
            ffmpeg.StartInfo.RedirectStandardError = true;

            // set the file name of our process, including the full path
            // (as well as quotes, as if you were calling it from the command-line)
            ffmpeg.StartInfo.FileName = ffmpegfile;

            // set the command-line arguments of our process, including full paths of any files
            // (as well as quotes, as if you were passing these arguments on the command-line)
            ffmpeg.StartInfo.Arguments = "-i " + sourceFile;

            // start the process
            ffmpeg.Start();

            // now that the process is started, we can redirect output to the StreamReader we defined
            errorreader = ffmpeg.StandardError;

            // wait until ffmpeg comes back
            ffmpeg.WaitForExit();

            // read the output from ffmpeg, which for some reason is found in Process.StandardError
            result = errorreader.ReadToEnd();

            // a little convoluded, this string manipulation...
            // working from the inside out, it:
            // takes a substring of result, starting from the end of the "Duration: " label contained within,
            // (execute "ffmpeg.exe -i somevideofile" on the command-line to verify for yourself that it is there)
            // and going the full length of the timestamp

            duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);
            return duration;
        
    

希望对你有帮助。

【讨论】:

【参考方案4】:

ffmpeg 还提供了一个特殊的应用程序ffprobe 用于读取元数据。我们为 .net 编写了一个包装器并提供了一个 nuget package,您可以在这里找到它:Alturos.VideoInfo

PM> Install-Package Alturos.VideoInfo

例子:

var videoFilePath = "myVideo.mp4";

var videoAnalyer = new VideoAnalyzer();
var analyzeResult = videoAnalyer.GetVideoInfo(videoFilePath);
var videoInfo = analyzeResult.VideoInfo;
//videoInfo.Format.Filename = "myVideo.mp4"
//videoInfo.Format.NbStreams = 1
//videoInfo.Format.NbPrograms = 0
//videoInfo.Format.FormatName = "mov,mp4,m4a,3gp,3g2,mj2"
//videoInfo.Format.FormatLongName = "QuickTime / MOV"
//videoInfo.Format.StartTime = 0
//videoInfo.Format.Duration = 120 //seconds
//videoInfo.Format.Size = 2088470 //bytes
//videoInfo.Format.BitRate = 139231
//videoInfo.Format.ProbeScore = 100
//videoInfo.Format.Tags["encoder"] = Lavf57.76.100
//videoInfo.Streams[0].CodecType = "video" //Video, Audio
//videoInfo.Streams[0]...

【讨论】:

这个库很好,但现在支持库不再维护,所以除非该库也随它一起提供,否则这将不起作用。 是的,我已经注意到了。你可以使用这个来源ffbinaries.com/downloads

以上是关于使用 C# 从 ASP.Net MVC 中的视频文件中获取视频元数据的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用C#从asp.net MVC中的枚举绑定下拉列表[重复]

asp.net mvc c# - 是不是可以从 CodeBehind 中的模型访问视图中文本框的值?

ASP.NET MVC - 使用 C# 将引用不同程序集的模型从控制器传递到视图

ASP.NET MVC C# - 显示类属性名称而不是 JSON 中的属性名称

ASP.NET MVC 小牛之路]02

asp.net mvc视图中的C#复选框事件不在表单内