【问题标题】:How to get video duration from mp4, wmv, flv, mov videos如何从 mp4、wmv、flv、mov 视频中获取视频时长
【发布时间】:2012-04-28 18:33:48
【问题描述】:

好的。实际上,我主要需要 mp4 格式。但是,如果也有可能获得其他类型,那就太好了。我只需要读取文件的持续时间。我如何使用 C# 4.0 做到这一点?

所以我需要的就是这个视频:13 minutes 12 seconds

我也可以使用 3 个第三方 exe。就像他们将有关文件的信息保存到文本文件一样。我可以解析那个文本文件。

谢谢。

【问题讨论】:

    标签: c# .net video mp4 duration


    【解决方案1】:

    我遇到了同样的问题,我们为 ffprobe Alturos.VideoInfo 构建了一个包装器。 您只需安装nuget 软件包即可使用它。 ffprobe 二进制文件也是必需的。

    PM> install-package Alturos.VideoInfo
    

    示例

    var videoFilePath = "myVideo.mp4";
    
    var videoAnalyer = new VideoAnalyzer("ffprobe.exe");
    var analyzeResult = videoAnalyer.GetVideoInfo(videoFilePath);
    
    var duration = analyzeResult.VideoInfo.Format.Duration;
    

    【讨论】:

      【解决方案2】:

      我认为您正在寻找 FFMPEG - https://ffmpeg.org/

      还有一些免费的替代品,您可以在这个问题中了解它们 - Using FFmpeg in .net?

         FFMpeg.NET
         FFMpeg-Sharp
         FFLib.NET
      

      您可以查看此链接,了解使用 FFMPEG 和查找持续时间的示例 - http://jasonjano.wordpress.com/2010/02/09/a-simple-c-wrapper-for-ffmpeg/

              public VideoFile GetVideoInfo(string inputPath)
              {
                  VideoFile vf = null;
                  try
                  {
                      vf = new VideoFile(inputPath);
                  }
                  catch (Exception ex)
                  {
                      throw ex;
                  }
                  GetVideoInfo(vf);
                  return vf;
              }
              public void GetVideoInfo(VideoFile input)
              {
                  //set up the parameters for video info
                  string Params = string.Format("-i {0}", input.Path);
                  string output = RunProcess(Params);
                  input.RawInfo = output;
      
                  //get duration
                  Regex re = new Regex("[D|d]uration:.((\\d|:|\\.)*)");
                  Match m = re.Match(input.RawInfo);
      
                  if (m.Success)
                  {
                      string duration = m.Groups[1].Value;
                      string[] timepieces = duration.Split(new char[] { ':', '.' });
                      if (timepieces.Length == 4)
                      {
                          input.Duration = new TimeSpan(0, Convert.ToInt16(timepieces[0]), Convert.ToInt16(timepieces[1]), Convert.ToInt16(timepieces[2]), Convert.ToInt16(timepieces[3]));
                      }
                  }
             }
      

      【讨论】:

      • 这是付费申请。他们只提供试用。这对我不起作用:(
      • @MonsterMMORPG ffrmpeg 是一款免费软件!见:ffmpeg.org/legal.html
      【解决方案3】:

      This answer 关于 P/Invoke for Shell32 让我想起了 Windows API Code Pack 来访问常见的 Windows Vista/7/2008/2008R2 API。

      使用包含的示例中的 PropertyEdit 演示非常容易,找出 Shell32 API 来获取各种媒体文件属性,例如持续时间。

      我假设安装正确的多路分解器也适用相同的先决条件,但它非常简单,因为它只需要添加对 Microsoft.WindowsAPICodePack.dllMicrosoft.WindowsAPICodePack.Shell.dll 的引用以及以下代码:

      using Microsoft.WindowsAPICodePack.Shell;
      using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
      
      using (ShellObject shell = ShellObject.FromParsingName(filePath))
      {
          // alternatively: shell.Properties.GetProperty("System.Media.Duration");
          IShellProperty prop = shell.Properties.System.Media.Duration; 
          // Duration will be formatted as 00:44:08
          string duration = prop.FormatForDisplay(PropertyDescriptionFormatOptions.None);
      }
      

      其他东西

      MPEG-4/AAC 音频媒体文件的一些常见属性:

      System.Audio.Format = {00001610-0000-0010-8000-00AA00389B71}
      System.Media.Duration = 00:44:08
      System.Audio.EncodingBitrate = ?56kbps
      System.Audio.SampleRate = ?32 kHz
      System.Audio.SampleSize = ?16 bit
      System.Audio.ChannelCount = 2 (stereo)
      System.Audio.StreamNumber = 1
      System.DRM.IsProtected = No
      System.KindText = Music
      System.Kind = Music
      

      如果您正在寻找可用的元数据,遍历所有属性很容易:

      using (ShellPropertyCollection properties = new ShellPropertyCollection(filePath))
      {
          foreach (IShellProperty prop in properties)
          {
              string value = (prop.ValueAsObject == null) ? "" : prop.FormatForDisplay(PropertyDescriptionFormatOptions.None);
              Console.WriteLine("{0} = {1}", prop.CanonicalName, value);
          }
      }
      

      【讨论】:

      • 非常简洁,但持续时间分辨率为秒 - 我也需要分数。请注意任何尝试此操作的人,您需要添加对 Windows7APICodePack-Core/Shell 的 NuGet 引用。
      • 喜欢它 :) 我现在完全关注 CodePack。请注意,该属性的原始值似乎特别是 10^-7 秒...我不知道是否实际上为所有文件类型提供了这么多详细信息,但您可以查找它。原始值在属性“.ValueAsObject”中,它是您需要从通用对象中剔除的 ulong。我将编辑答案以尝试添加此内容。
      【解决方案4】:
      StreamReader errorreader;
      string InterviewID = txtToolsInterviewID.Text;
      
      Process ffmpeg = new Process();
      
      ffmpeg.StartInfo.UseShellExecute = false;
      ffmpeg.StartInfo.ErrorDialog = false;
      ffmpeg.StartInfo.RedirectStandardError = true;
      
      ffmpeg.StartInfo.FileName = Server.MapPath("ffmpeg.exe");
      ffmpeg.StartInfo.Arguments = "-i " + Server.MapPath("videos") + "\\226.flv";
      
      
      ffmpeg.Start();
      
      errorreader = ffmpeg.StandardError;
      
      ffmpeg.WaitForExit();
      
      string result = errorreader.ReadToEnd();
      
      string duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00.00").Length);
      

      【讨论】:

        【解决方案5】:

        也使用 Windows Media Player 组件,我们可以获得视频的时长。
        以下代码 sn-p 可以帮助你们:

        using WMPLib;
        // ...
        var player = new WindowsMediaPlayer();
        var clip = player.newMedia(filePath);
        Console.WriteLine(TimeSpan.FromSeconds(clip.duration));
        

        并且不要忘记添加 wmp.dll 的引用,这将是 存在于 System32 文件夹中。

        【讨论】:

          【解决方案6】:

          我发现NReco.VideoInfo library 是最好的选择,而且比上面的一些更简单。给库一个文件路径并吐出元数据很简单:

          var ffProbe = new FFProbe();
          var videoInfo = ffProbe.GetMediaInfo(blob.Uri.AbsoluteUri);
          return videoInfo.Duration.TotalMilliseconds;
          

          【讨论】:

          • 请注意商业用途有一个付费许可证
          【解决方案7】:

          您可以通过 DirectShow.NET 包装库使用 DirectShow API MediaDet 对象。有关代码示例,请参见 Getting length of videoget_StreamLength 以秒为单位获取持续时间。这假设 Windows 已安装 MPEG-4 解复用器(需要 Windows 7 之前的第三方组件,我相信这同样适用于另一个 answer by cezor,尽管可以免费重新分发组件)。

          【讨论】:

          • 这个 DirectShot API 在哪里?你也能给我这个第三部分的网址吗?或者你的意思是像 k lite mega 编解码器包?
          • 感谢这一行给出了正确的持续时间为秒:mediaDet.get_StreamLength(out mediaLength);
          • DirectShow 是核心 Windows API,您始终拥有它。 Wrapper 库directshownet.sourceforge.net 是您到 DrietShow 的 C# 桥梁。 MP4 文件的问题是您需要安装解复用器。由于它是专利技术,这给生活带来了麻烦——默认情况下没有人。 gdcl.co.uk/mpeg4 有一个很好的可安装/可再分发选项@您只需要弄清楚如何重新分发和安装它。
          • 好吧,这在 windows server 2008 r2 上失败了,但在我的本地计算机上工作。安装windows服务器需要什么? k lite mega 编解码器包可以工作吗?
          • 是的,我相信是的。或者,使用上面来自 GCDL 的链接。您需要从那里获取 DLL,并在目标系统中 regsvr32 它们 - 这应该足够了。
          【解决方案8】:

          FFMPEG 项目有一个名为 ffprobe 的工具,它可以为您提供多媒体文件所需的信息,并以格式良好的 JSON 格式输出信息。

          this answer 为例。

          【讨论】:

            【解决方案9】:

            您也可以使用 windows 媒体播放器,尽管它不支持您请求的所有文件类型

            using WMPLib;
            
            public Double Duration(String file)
                {
                    WindowsMediaPlayer wmp = new WindowsMediaPlayerClass();
                    IWMPMedia mediainfo = wmp.newMedia(file);
                    return mediainfo.duration;
                }
            }
            

            【讨论】:

            • 谢谢,但该应用程序可以在 windows server 2008 上运行。我想他们没有 windows 媒体播放器。
            • @MonsterMMORPG 看来你是对的stackoverflow.com/a/13929540/188926
            【解决方案10】:

            恕我直言,您可以使用MediaInfo,它可以为您提供有关媒体文件的大量信息。
            它有一个 CLI,因此您可以从代码中使用它并获取所需的信息。
            你可以看看this link

            【讨论】:

            • 你好。我无法添加 mediainfodll 作为参考。你知道为什么吗 ?这里的错误信息:img707.imageshack.us/img707/8130/hataow.png
            • @MonsterMMORPG:您必须使用参数调用应用程序并获取输出,不能将其用作解决方案中的参考
            猜你喜欢
            • 2011-08-26
            • 2021-05-21
            • 2011-09-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多