.NET读取视频信息、视频截图

在.NET中处理视频是一件痛苦的事情,.NET并没有提供视频处理的类。于是咱们只能找一些第三方的类库或者自己实现,在项目时间比较赶的情况下,自己实现是不可能的了,而且说不定会留下很多坑。所以一般情况下,咱们都是找一些靠谱的第三方类库,毕竟别人确实实现得蛮好的。
这次的项目是一个资讯发布APP,其中一个模块功能有些类似微信朋友圈,发布内容需要支持图片、音频、视频等。其他的都很好处理,但视频的处理着实让我费了一番劲儿,之前也没有接触过视频处理的项目,甚至对视频处理的了解也挺少的。于是我Google了大半天(国内搜索引擎很少相关资料,此处建议使用Google Code),找到了一些解决方案,我选取了其中的2个。

1、AVBlocks

不得不说AVBlocks确实是做得挺不错的,其主要功能是处理视频、音频、图片等多媒体文件;AVBlocks官网提供了非常详细的Demo,比较可惜的是Demo的注释跟说明比较少(或者只是我没有发现),我在开始工作前把这个Demo里面38个项目通读了一遍(基本每个项目只包含一种功能,代码简洁)。

a)功能简介

主要包括视频的格式、流、比特率、颜色格式(Color Format)、宽高比、分辨率、帧率、扫描方式(Scan Type;这个参数我是真的不认识);

获取音频、图片信息我还没用到,不过据官网的介绍看起来还是挺好用的,AVBlocks支持的格式很多,值得一用。

b)使用方法

使用AVBlocks的方法很简单,直接在你的项目中引用 AVBlocks.clr4.x64.dll ,然后复制 AVBlocks64.dll 到你的项目生成目录下(如果是 WinForm,则复制到输出目录根目录;如果是 ASP.NET,则复制到输出目录 bin 目录)就可以了。

如果运行时报以下错误:
“无法加载 DLL“AVBlocks64.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。”
不用怀疑,肯定是你没有把AVBlocks64.dll复制到输出目录下。

c)上线注意事项

之所以写这部分是因为我在上线的时候就傻乎乎跳进了一个坑,Windows Server 2008/2008 R2/2012/2012 R2等服务器默认是没有安装wmvcore.dll。这需要我们手动安装Media Foundation(媒体基础)或者Desktop Experience(桌面体验)功能。我选择安装“桌面体验”功能。
大概操作是这样:服务器管理器->功能->添加,然后找到“桌面体验”,勾选、确定,安装完成后重启就可以了。

不然会一直报错“未将对象引用设置到对象的实例”。其实官网有说明,只是我一开始没留意。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

下面是这部分的代码:

public class VideoInfo
{
//public StreamType Container { get; set; }
//public int Streams { get; set; }
public string FileName { get; set; }
public string CaptureFile { get; set; }
public MediaType MediaType { get; set; }
public StreamType StreamType { get; set; }
public StreamSubType StreamSubType { get; set; }
public int Id { get; set; }
public double Duration { get; set; }
public int Bitrate { get; set; }
public BitrateMode BitrateMode { get; set; }
public ColorFormat ColorFormat { get; set; }
public int DisplayRatioWidth { get; set; }
public int DisplayRatioHeight { get; set; }
public bool FrameBottomUp { get; set; }
public int FrameWidth { get; set; }
public int FrameHeight { get; set; }
public double FrameRate { get; set; }
public ScanType ScanType { get; set; }
}

public static VideoInfo GetVideoInfo(string inputFile)
{
VideoInfo videoInfo = new VideoInfo();
using (MediaInfo info = new MediaInfo())
{
info.Inputs[0].File = inputFile;

if (!info.Open())
{
return null;
}

videoInfo = GetStreams(info)[0];
}

// videoInfo.CaptureFile = CatchImg(inputFile, videoInfo.FrameWidth, videoInfo.FrameHeight);

return videoInfo;
}

private static List<VideoInfo> GetStreams(MediaInfo mediaInfo)
{
List<VideoInfo> videoInfos = new List<VideoInfo>();
foreach (var socket in mediaInfo.Outputs)
{
VideoInfo videoInfo = new VideoInfo();

for (int streamIndex = 0; streamIndex < socket.Pins.Count; streamIndex++)
{
StreamInfo si = socket.Pins[streamIndex].StreamInfo;
videoInfo.MediaType = si.MediaType;
videoInfo.StreamType = si.StreamType;
videoInfo.StreamSubType = si.StreamSubType;
videoInfo.Id = si.ID;
videoInfo.Duration = si.Duration;

if (MediaType.Video == si.MediaType)
{
VideoStreamInfo vsi = si as VideoStreamInfo;
videoInfo.Bitrate = vsi.Bitrate;
videoInfo.BitrateMode = vsi.BitrateMode;
videoInfo.ColorFormat = vsi.ColorFormat;
videoInfo.DisplayRatioWidth = vsi.DisplayRatioWidth;
videoInfo.DisplayRatioHeight = vsi.DisplayRatioHeight;
videoInfo.FrameBottomUp = vsi.FrameBottomUp;
videoInfo.FrameWidth = vsi.FrameWidth;
videoInfo.FrameHeight = vsi.FrameHeight;
videoInfo.FrameRate = vsi.FrameRate;
videoInfo.ScanType = vsi.ScanType;
}

videoInfos.Add(videoInfo);
}
}
return videoInfos;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
2、FFMpeg

在项目中,我需要随机截取视频中其中一帧的图片作为视频封面,所以我找到了FFMpeg只是简单的做个截图功能。
其实FFMpeg功能很强大,想转换视频格式什么的,推荐大家有兴趣读一下这篇文章:

A Simple c# Wrapper for ffMpeg

使用也很简单,就只是调用ffMpeg.exe传入参数即可,具体参数说明可参考官方说明。
要是找不到FFMpeg.exe的下载的话,看这里:http://download.csdn.net/download/u012843100/9930545

我简单介绍下我项目中的使用:

a)复制ffMpeg.exe到系统目录下,目录随意,在第二步进行配置;
b)需在Web.config的appSettings节点中配置ffmpeg.exe的路径,<add key="ffmpeg" value="plugins\ffmpeg.exe" />;
c)上代码;
1
2
3

/// <summary>
/// 使用ffMpeg.exe截取视频图片(第一帧)
/// *需在Web.config的appSettings节点中配置ffmpeg.exe的路径*
/// *<add key="ffmpeg" value="plugins\ffmpeg.exe" />*
/// </summary>
/// <param name="vedioPath">视频路径</param>
/// <param name="saveImgWidth">保存的图片宽度</param>
/// <param name="saveImgHeight">保存的图片高度</param>
/// <returns>保存后的图片路径(去除基路径)</returns>
public static string CatchImg(string vedioPath, int saveImgWidth, int saveImgHeight)
{
string ffmpeg = AppDomain.CurrentDomain.BaseDirectory + "\\" + System.Configuration.ConfigurationSettings.AppSettings["ffmpeg"];
if ((!System.IO.File.Exists(ffmpeg)) || (!System.IO.File.Exists(vedioPath)))
{
return "";
}

string saveImgPath = System.IO.Path.ChangeExtension(vedioPath, ".jpg");
string saveImgSize = string.Format("{0}x{1}", saveImgWidth, saveImgHeight);
ProcessStartInfo startInfo = new ProcessStartInfo(ffmpeg);
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.Arguments = string.Format(" -i \"{0}\" -y -f image2 -t 0.001 -s \"{1}\" \"{2}\"", vedioPath, saveImgSize, saveImgPath);
System.Diagnostics.Process.Start(startInfo);

return saveImgPath.Replace(AppDomain.CurrentDomain.BaseDirectory, "");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
以上就是这次我关于.NET视频处理的一些经验。

最后附上这个类的完整代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using PrimoSoftware.AVBlocks;

namespace JHD.Utils
{
public class AvInfoUtil
{
public class VideoInfo
{
//public StreamType Container { get; set; }
//public int Streams { get; set; }
public string FileName { get; set; }
public string CaptureFile { get; set; }
public MediaType MediaType { get; set; }
public StreamType StreamType { get; set; }
public StreamSubType StreamSubType { get; set; }
public int Id { get; set; }
public double Duration { get; set; }
public int Bitrate { get; set; }
public BitrateMode BitrateMode { get; set; }
public ColorFormat ColorFormat { get; set; }
public int DisplayRatioWidth { get; set; }
public int DisplayRatioHeight { get; set; }
public bool FrameBottomUp { get; set; }
public int FrameWidth { get; set; }
public int FrameHeight { get; set; }
public double FrameRate { get; set; }
public ScanType ScanType { get; set; }
}

public static VideoInfo GetVideoInfo(string inputFile)
{
VideoInfo videoInfo = new VideoInfo();
using (MediaInfo info = new MediaInfo())
{
info.Inputs[0].File = inputFile;

if (!info.Open())
{
return null;
}

videoInfo = GetStreams(info)[0];
}

videoInfo.CaptureFile = CatchImg(inputFile, videoInfo.FrameWidth, videoInfo.FrameHeight);

return videoInfo;
}

private static List<VideoInfo> GetStreams(MediaInfo mediaInfo)
{
List<VideoInfo> videoInfos = new List<VideoInfo>();
foreach (var socket in mediaInfo.Outputs)
{
VideoInfo videoInfo = new VideoInfo();

for (int streamIndex = 0; streamIndex < socket.Pins.Count; streamIndex++)
{
StreamInfo si = socket.Pins[streamIndex].StreamInfo;
videoInfo.MediaType = si.MediaType;
videoInfo.StreamType = si.StreamType;
videoInfo.StreamSubType = si.StreamSubType;
videoInfo.Id = si.ID;
videoInfo.Duration = si.Duration;

if (MediaType.Video == si.MediaType)
{
VideoStreamInfo vsi = si as VideoStreamInfo;
videoInfo.Bitrate = vsi.Bitrate;
videoInfo.BitrateMode = vsi.BitrateMode;
videoInfo.ColorFormat = vsi.ColorFormat;
videoInfo.DisplayRatioWidth = vsi.DisplayRatioWidth;
videoInfo.DisplayRatioHeight = vsi.DisplayRatioHeight;
videoInfo.FrameBottomUp = vsi.FrameBottomUp;
videoInfo.FrameWidth = vsi.FrameWidth;
videoInfo.FrameHeight = vsi.FrameHeight;
videoInfo.FrameRate = vsi.FrameRate;
videoInfo.ScanType = vsi.ScanType;
}

videoInfos.Add(videoInfo);
}
}
return videoInfos;
}

/// <summary>
/// 使用ffMpeg.exe截取视频图片(第一帧)
/// *需在Web.config的appSettings节点中配置ffmpeg.exe的路径*
/// *<add key="ffmpeg" value="plugins\ffmpeg.exe" />*
/// </summary>
/// <param name="vedioPath">视频路径</param>
/// <param name="saveImgWidth">保存的图片宽度</param>
/// <param name="saveImgHeight">保存的图片高度</param>
/// <returns>保存后的图片路径(去除基路径)</returns>
public static string CatchImg(string vedioPath, int saveImgWidth, int saveImgHeight)
{
string ffmpeg = AppDomain.CurrentDomain.BaseDirectory + "\\" + System.Configuration.ConfigurationSettings.AppSettings["ffmpeg"];
if ((!System.IO.File.Exists(ffmpeg)) || (!System.IO.File.Exists(vedioPath)))
{
return "";
}

string saveImgPath = System.IO.Path.ChangeExtension(vedioPath, ".jpg");
string saveImgSize = string.Format("{0}x{1}", saveImgWidth, saveImgHeight);
ProcessStartInfo startInfo = new ProcessStartInfo(ffmpeg);
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.Arguments = string.Format(" -i \"{0}\" -y -f image2 -t 0.001 -s \"{1}\" \"{2}\"", vedioPath, saveImgSize, saveImgPath);
System.Diagnostics.Process.Start(startInfo);

return saveImgPath.Replace(AppDomain.CurrentDomain.BaseDirectory, "");
}
}
}
---------------------
作者:lyzcren
来源:CSDN
原文:https://blog.csdn.net/u012843100/article/details/77113385
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/zxtceq/p/10121404.html

时间: 2024-10-03 01:07:34

.NET读取视频信息、视频截图的相关文章

SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续篇

引言 上一篇 <Socket与站点保密应用 (隐藏链接的视频下载)>大大咧咧地从 WEB 讲 Socket.再到 TCP/IP 等协议,又再讲到 Wireshark 怎样抓IP包分析.最还要复习一下路由与网络的知识.真的涉及面太广了,仅仅能蜻蜓点水一一带过,只是将多领域的知识串烧也是不错的,能够起到一个归纳的作用.这篇针对 Flash 来进行.写作思路以解决这个问题的过程行为线索. 依次展示怎样使用 Flex Air 的 ServerSocket 和 Socket 实现简化版本号的 HTTP

C#实现通过ffmpeg从flv视频文件中截图的方法

本文实例讲述了C#实现通过ffmpeg从flv视频文件中截图的方法.分享给大家供大家参考.具体分析如下: 需要先下载ffmpeg,这是开源的,代码如下所示: 代码如下: using System; using System.Configuration; public class PublicMethod:System.Web.UI.Page { public PublicMethod() { } //文件路径 public static string ffmpegtool = "ffmpeg/f

IOS从视频中获取截图

从视频中获取截图: NSString *movpath =[[NSBundle mainBundle] pathForResource:@”iosxcode4″ ofType:@”mov”]; mpviemController =[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:movpath]]; MPMoviePlayerController *mp=[mpviemController

Android必知必会-获取视频文件的截图、缩略图

背景 公司最近要求给我负责的APP加上视频录制和发布的功能,我简单的完成了基本的录制和视频压缩功能,后来发现发布接口需要上传视频的截图,网上搜索了一下资料,在这里整理一下. 代码实现 /** * 获取视频文件截图 * * @param path 视频文件的路径 * @return Bitmap 返回获取的Bitmap */ public static Bitmap getVideoThumb(String path) { MediaMetadataRetriever media = new Me

使用HTML 5捕捉音频与视频信息

长期以来,音频与视频信息的捕捉一直是Web开发中的一个难点.许多年来,我们一直依赖浏览器插件来实现这个需求. 在HTML 5中,出现了许多可以访问硬件设备的API,例如访问GPS设备的Geolocation API.访问accelerometer设备的Orientation API.访问GPU设备的WebGL API.访问音频播放设备的Web Audio API等等.这些API是非常强大的,因为开发者可以直接通过编写JavaSccript脚本代码来访问底层硬件设备. 本文介绍一种新的API,该A

OpenCV视频读取播放,视频转换为图片

转载请注明出处!!! http://blog.csdn.net/zhonghuan1992 OpenCV视频读取播放,视频转换为图片 介绍几个有关视频读取的函数: VideoCapture::VideoCapture VideoCapture能够从文件里或者摄像头中读取视频,这是提供给C++的接口的.C的接口是CvCapture结构.        <span style="white-space:pre"> </span>C++: VideoCapture::

【FFMpeg视频开发与应用基础】五、调用FFMpeg SDK封装音频和视频为视频文件

<FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK>视频教程已经在"CSDN学院"上线,视频中包含了从0开始逐行代码实现FFMpeg视频开发的过程,欢迎观看!链接地址:FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK 工程代码地址:FFmpeg_Tutorial 音频和视频的封装过程为解封装的逆过程,即将独立的音频数据和视频数据按照容器文件所规定的格式封装为一个完整的视频文件的过程.对于大多数消费者来说,视频封装的容器是大家最为熟悉的,因为它直接

使用yo-get下载视频网站视频或其他

使用yo-get下载视频网站视频或其他 文/玄魂 目录 使用yo-get下载视频网站视频或其他... 1 前言... 1 1.1 下载.安装... 1 依赖... 1 exe安装... 1 pip安装... 1 Antigen安装... 1 Git 克隆源码... 1 Homebrew 安装... 1 1.2  基本使用... 1 下载视频网站视频... 1 下载任何指定文件... 1 利用google搜索并下载视频... 1 中断和继续... 1 自定义下载文件路径和名称... 1 设置代理.

“小视频”拯救视频分享?

在视频分享领域,短视频也好.小视频也罢,都受制于发布者自身技术的"不过关"而暂时很难普及.但这并不妨碍短视频作为一种移动互联网的信息分享手段,逐步实现扩散. 文/张书乐 刊载于<互联网经济>2014年12月刊 2014年国庆前夕,微信推出了ios 6.0版本,增加了小视频.微信卡包等全新功能.特别是小视频功能,尤为引人关注.在很多人看来,一直不温不火的短视频领域,似乎将因为微信这个移动社交的巨擘的加入,真正成为流行时尚元素.几乎在微信动作的前后,不少互联网企也纷纷推出了带有

JavaWEB中读取配置信息

第一种方法是使用java.io和java.util包,缺点是路径的概念要清晰, 例子: Properties prop = new Properties(); InputStream in = getClass().getResourceAsStream("/common.properties"); try { prop.load(in); pool = new JedisPool(config, prop.getProperty("pay.redis.url"))