参考网址:https://blog.csdn.net/u013810234/article/details/57471780

以下为本次测试用到的音、视频格式:

audio :”.wav;.mp3;.wma;.ra;.mid;.ogg;.ape;.au;.aac;”;

vedio :”.mp4;.mpg;.mpeg;.avi;.rm;.rmvb;.wmv;.3gp;.flv;.mkv;.swf;.asf;”;

Note:
1. 测试音、视频均为对应格式的有效文件(下载自地址:包含了各种可供测试音视频格式,且不断更新中。。);
2. 若某音/视频时长为0,表示对应库、组件无法解码文件,即不支持该格式;
3. 类之间的关系:定义了Duration父类,三个测试方案均继承自Duration,并重写父类GetDuration方法。

获取时长父类

public abstract class Duration
{
/// <summary>
/// Abstract method of getting duration(ms) of audio or vedio
/// </summary>
/// <param name="filePath">audio/vedio's path</param>
/// <returns>Duration in original format, duration in milliseconds</returns>
public abstract Tuple<string, long> GetDuration(string filePath);

/// <summary>
/// Convert format of "00:10:16" and "00:00:19.82" into milliseconds
/// </summary>
/// <param name="formatTime"></param>
/// <returns>Time in milliseconds</returns>
public long GetTimeInMillisecond(string formatTime)
{
double totalMilliSecends = 0;

if (!string.IsNullOrEmpty(formatTime))
{
string[] timeParts = formatTime.Split(':');
totalMilliSecends = Convert.ToInt16(timeParts[0]) * 60 * 60 * 1000
+ Convert.ToInt16(timeParts[1]) * 60 * 1000
+ Math.Round(double.Parse(timeParts[2]) * 1000);
}

return (long)totalMilliSecends;
}
}
使用NAudio.dll

下载、引用NAudio.dll;
由于NAudio本身主要用于处理音频,用其获取视频时长并不合理(仅作统一测试),所以多数格式不支持,不足为奇;
public class ByNAudio : Duration
{
/// <summary>
/// Get duration(ms) of audio or vedio by NAudio.dll
/// </summary>
/// <param name="filePath">audio/vedio's path</param>
/// <returns>Duration in original format, duration in milliseconds</returns>
/// <remarks>return value from NAudio.dll is in format of: "00:00:19.820"</remarks>
public override Tuple<string, long> GetDuration(string filePath)
{
TimeSpan ts;
try
{
using (AudioFileReader audioFileReader = new AudioFileReader(filePath))
{
ts = audioFileReader.TotalTime;
}
}
catch (Exception)
{
/* As NAudio is mainly used for processing audio, so some formats may not surport,
* just use 00:00:00 instead for these cases.
*/
ts = new TimeSpan();
//throw ex;
}

return Tuple.Create(ts.ToString(), GetTimeInMillisecond(ts.ToString()));
}
}

NAudio结果:

使用Shell32.dll

引用Shell32.dll,在COM里;
Windows自带的组件,仅支持常见的音视频格式;
public class ByShell32 : Duration
{
/// <summary>
/// Get duration(ms) of audio or vedio by Shell32.dll
/// </summary>
/// <param name="filePath">audio/vedio's path</param>
/// <returns>Duration in original format, duration in milliseconds</returns>
/// <remarks>return value from Shell32.dll is in format of: "00:10:16"</remarks>
public override Tuple<string, long> GetDuration(string filePath)
{
try
{
string dir = Path.GetDirectoryName(filePath);

// From Add Reference --> COM
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder folder = shell.NameSpace(dir);
Shell32.FolderItem folderitem = folder.ParseName(Path.GetFileName(filePath));

string duration = null;

// Deal with different versions of OS
if (Environment.OSVersion.Version.Major >= 6)
{
duration = folder.GetDetailsOf(folderitem, 27);
}
else
{
duration = folder.GetDetailsOf(folderitem, 21);
}

duration = string.IsNullOrEmpty(duration) ? "00:00:00" : duration;
return Tuple.Create(duration, GetTimeInMillisecond(duration));
}
catch (Exception ex)
{
throw ex;
}
}
}

Shell32结果:

使用FFmpeg.exe

下载FFmpeg.exe;
异步调用“ffmpeg -i 文件路径”命令,获取返回文本,并解析出Duration部分;
FFmpeg是对音视频进行各种处理的一套完整解决方案,包含了非常先进的音频/视频编解码库,因此可处理多种格式(本次测试的音、视频格式均可以进行有效解码)。
public class ByFFmpeg : Duration
{
private StringBuilder result = new StringBuilder(); // Store output text of ffmpeg

/// <summary>
/// Get duration(ms) of audio or vedio by FFmpeg.exe
/// </summary>
/// <param name="filePath">audio/vedio's path</param>
/// <returns>Duration in original format, duration in milliseconds</returns>
/// <remarks>return value from FFmpeg.exe is in format of: "00:00:19.82"</remarks>
public override Tuple<string, long> GetDuration(string filePath)
{
GetMediaInfo(filePath);
string duration = MatchDuration(result.ToString());

return Tuple.Create(duration, GetTimeInMillisecond(duration));
}

// Call exe async
private void GetMediaInfo(string filePath)
{
result.Clear(); // Clear result to avoid previous value's interference

Process p = new Process();
p.StartInfo.FileName = "ffmpeg.exe";
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = string.Concat("-i ", filePath);
p.ErrorDataReceived += new DataReceivedEventHandler(OutputCallback);

p.Start();
p.BeginErrorReadLine();

p.WaitForExit();
p.Close();
p.Dispose();
}

// Callback funciton of output stream
private void OutputCallback(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
result.Append(e.Data);
}
}

// Match the 'Duration' section in "ffmpeg -i filepath" output text
private string MatchDuration(string text)
{
string pattern = @"Duration:\s(\d{2}:\d{2}:\d{2}.\d+)";
Match m = Regex.Match(text, pattern);

return m.Groups.Count == 2 ? m.Groups[1].ToString() : string.Empty;
}
}

ffmpeg -i filePath
……[mp3 @ 0233ca60] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from ‘2012.mp3’:
Duration: 00:22:47.07, start: 0.000000, bitrate: 127 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 128 kb/s
At least one output file must be specified
Note:以上为ffmpeg -i 命令的输出值,需要匹配到Duration的时长部分。

FFmpeg结果:

Source Code(含测试音、视频文件): Github

获取音、视频时长(NAudio,Shell32,FFmpeg)的更多相关文章

  1. asp.net 获取音视频时长 的方法

    http://www.evernote.com/l/AHPMEDnEd65A7ot_DbEP4C47QsPDYLhYdYg/ 日志:   1.第一种方法:   调用:shell32.dll ,win7 ...

  2. jave 计算音视频时长

    File source = new File("视频.mp4"); Encoder encoder = new Encoder(); try { MultimediaInfo in ...

  3. vue / js使用video获取视频时长

    项目中遇到上传视频功能,需要有预览和获取视频时长功能,因之前使用upload(有需要的话可以参考下我之前的文章),这里就不赘述,直接用来上传视频,不过在上传之前和上传成功后的钩子里,获取不到时长: 没 ...

  4. vue 获取视频时长

    参考资料:js获取上传音视频文件的时长 直接通过element-ui自带的上传组件结合js即可,代码如下: HTML: <el-upload class="upload-demo&qu ...

  5. windows server 2008 R2服务器无法通过ShellClass获取mp3音乐时长

    我们先看一段代码,获取mp3播放时长: #region GetMediaDetailInfo 获取媒体文件属性信息 /// <summary> /// 获取媒体文件属性信息 /// < ...

  6. iOS:Gif动画功能(显示gif动画、获取gif动画时长、获取gif动画执行次数)

    一.简单介绍 gif动画是iOS开发中很常用的一个功能,有的是为了显示加载视频的过程,更多的是为了显示一个结果状态(动画更直观). 那么如何执行gif动画,方法有很多.(这里只写一下方法三,前两种之前 ...

  7. Android获取视频音频的时长的方法

    android当中获取视频音频的时长,我列举了三种. 1:获取视频URI后获取cursor cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore ...

  8. Long类型时间如何转换成视频时长?

    数据库中存放的视频时长是一个Long类型的毫秒/秒时间,现在需要把这个时间转换成标准的视频时长格式,在我看来这应该是一个很常用的转化有一个很常用的转换方法工具才对,可是我百度找了许久,没有一个简单直观 ...

  9. javascript 获得以秒计的视频时长

    <!DOCTYPE html> <html> <body> <h3>演示如何访问 VIDEO 元素</h3> <video id=&q ...

随机推荐

  1. 整数m去掉n位后剩下最大(小)值

    题目描述 给定一个正整数(<=255位),从中删去n位后,使得剩下的数字组成的新数最小(大): 思路:从左到右开始扫描,两两比较,如果是前一位比后一位大,则删去前大的一位,直到删完所有的n位: ...

  2. JAVA实操项目:转账接口设计

    在一个项目中,一般都会支付相关的业务,而涉及到支付必定会有转账的操作,转账这一步想起来算是比较关键的部分,这个接口的设计能力,也大致体现出一个人的水平. 昨天碰到了一个题目: 尝试用java编写一个转 ...

  3. Android 关于虹软人脸识别SDK引擎使用总结

    虹软 最近开放了人脸识别的SDK引擎(免费的哦),刚好有Android版的,就体验了一波.下面来说说Android版的SDK使用心得: ArcFace 虹软人脸认知引擎简介 目前开放的版本有人脸比对( ...

  4. html+css+js实现类似音乐app似的列表播放

    最近做了一个类似于音乐app里面列表播放的功能,主要是音频播放和按钮状态的联动: 界面如下: 如上图所示 上面有一个播放按钮 下面有一个播放列表 上面还有一个歌曲长度的总时长 上面一个按钮能控制下面所 ...

  5. 配置java环境jdk

    最近尝试改公司的项目中的一个后台管理系统,前后台都让我一个做,所以要配置一下java环境: 1. 按装jdk 1.6//2. 安装eclipse3. 安装maven4. 安装eclispe的maven ...

  6. 最长连续子序列 Longest Consecutive Sequence

    2018-11-25 16:28:09 问题描述: 问题求解: 方法一.如果不要求是线性时间的话,其实可以很直观的先排序在遍历一遍就可以得到答案,但是这里明确要求是O(n)的时间复杂度,那么就给了一个 ...

  7. C# 遍历文件夹筛选目标文件

    有近400G的数据,首先需要写程序把目标文件标准化名称(相当耗时,各种情形,间接说明在数据采集过程中标准化操作的重要性,这样会给后续处理带来很多不必要的麻烦和消耗) 网上找了个方法还不错,还有一种递归 ...

  8. linux服务器规格查看

    性能测试前,需要确定服务器规格. 下面汇总下如何查看linux的CPU等规格 1. 查看服务器CPU个数 1)查看物理CPU个数: cat /proc/cpuinfo |grep "phys ...

  9. tomcat ----> 启动,关闭和配置等等

    1.启动 在tomcat安装目录的bin文件中双击startup.bat. 2.关闭 在tomcat安装目录的bin文件中双击shutdown.bat. 3.配置tomcat-user.xml文件 ( ...

  10. 安装EF实体模型框架

    Data Access and Storage > 学习 > Entity Framework > 开始操作 > 空间 - EF 设计器 本视频和分步演练介绍如何使用实体框架设 ...