参考网址: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

转载于:https://www.cnblogs.com/zxtceq/p/10121411.html

获取音、视频时长(NAudio,Shell32,FFmpeg)相关推荐

  1. php 获取音视频时长,PHP 利用getid3 获取音频文件时长等数据

    1.首先,我们需要先下载一份PHP类-getid3 https://codeload.github.com/JamesHeinrich/getID3/zip/master 2.解压刚才下载好的文件,拿 ...

  2. Java获取3gp视频时长

    Java获取3gp视频时长,其他格式的好像也可以,没有全部去试 /*** 获取视频的时间长*/public static String getVideoTime(String destFile) {S ...

  3. 上传时获取video视频时长

    本来开心的划水摸鱼,然后一个后端的卧龙过来跟我说上传需要把视频时长传递他,我当时第一反应就是你能获取吗? 然后就被告知不好获取,好吧那就只能自己写咯,整体就是在页面中创建一个video 的dom 节点 ...

  4. python获取网页播放视频时长_python 获取目录视频时长,大小

    #!/usr/bin/python # -*- coding:utf-8 -*- import os import sys import re import xlwt import csv from ...

  5. 使用ffmpeg调整视频时长倍速

    简介:通过ffmpeg调整视频时长,既可以尽量因调整视频时长引起的对视频质量的侵害,也能避免使用第三方工具收费或者广告问题,从而更干净安全的获取目标视频时长转换. 相关攻略: 利用ffmpeg将avi ...

  6. 【懒人系列】快手获取当前播放视频时长

    文章目录 前言 实现方法 总结 前言 上一篇文章我们留了个不大不小的问题:如何获取当前播放视频时长,进而视频播放完毕后自动翻页? 现在我们通过快手极速版App进行探讨和实现. 众所周知,Android ...

  7. java ffmpeg 获取视频时长_Java通过调用FFMPEG获取视频时长

    FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库l ...

  8. Android之通过文件绝对路径获取音视频的时长和视频的缩略图

    1 需求 遍历一个文件夹,需要获取音视频的时长和视频的第一帧图像 2 关键代码实现 获取本地音视频的时长(这里计算出来的是秒为单位),如果文件不是音视频,下面的函数会发生异常,也就是返回0,我们除了通 ...

  9. Java通过FFMPEG获取视频时长

    2019独角兽企业重金招聘Python工程师标准>>> Java通过FFMPEG获取视频时长 详见https://www.yz1618.cn/view/19 转载于:https:// ...

最新文章

  1. 强制解除占用端口,最快速方便的解除占用端口,端口占用解决方案大全
  2. 查询学生选修课程管理系统java_JAVA数据库课程设计学生选课管理系统的
  3. CAP 原则与 BASE 理论
  4. django-删除学生数据
  5. springMVC下载FTP上的文件
  6. 《Python 快速入门》C站最全Python标准库总结
  7. 如何确认IAR软件有没有激活
  8. 深圳市商务局2022年度中央资金(跨境电子商务企业市场开拓扶持事项)申报指南
  9. nextjs的发布,pm2发布nextjs项目
  10. rocketmq错误迁移导致问题排查
  11. graphpad细胞增殖曲线_应用GraphPad Prism制作生存曲线详细图文过程
  12. 顺丰快递:请签收Netty灵魂十连问
  13. MySQL数据库怎么进行分库分表?
  14. python罗马数字转换阿拉伯数字_20202427-张启辰《Python3初学:罗马数字转阿拉伯数字》...
  15. 最新IOS xcode12真机调试步骤
  16. 简单大方的java自我介绍,简单大方的自我介绍
  17. CDA深度分享:数据自由之路——数据产品及数据分析职业发展路径
  18. 韩顺平老师的linux基础课(复习笔记)
  19. Drying POJ - 3104 二分
  20. 【C语言】设计实现M*N矩阵和N*M矩阵相乘

热门文章

  1. win10磁盘100官方解释_win10磁盘分区管理工具大变脸,现代磁盘管理工具喷薄而出...
  2. 杂谈!了解一些额外知识,让你的前端开发锦上添花
  3. 前端遇到瓶颈了怎么办?
  4. php更新数据步骤,Thinkphp5模型更新数据方法
  5. python钓鱼网站_学习笔记6.0 Django入门创建一个钓鱼网站
  6. 华为鸿蒙系统发展时间2021年,耗时八年打造国产系统,华为鸿蒙OS质疑声不断,它才是真正未来...
  7. go kegg_对miRNA进行go和kegg等功能数据库数据库注释
  8. linux arm交叉编译ko,Ubuntu嵌入式交叉编译环境arm-linux-gcc
  9. 在powerpoint中默认的视图是_专升本计算机《Word、Excel、Powerpoint》知识点
  10. STM8学习笔记---点亮LED灯