利用Mplayer 实现视频连拍
来源:互联网 发布:微信扫号软件 编辑:程序博客网 时间:2024/04/27 15:26
主要利用Mplayer 作视频截图,先前试过ffmpeg 但是截一张指定较长时间的视频很慢如:截取20:00:00等半天才截出图片来,所以换了mplayer 来做,很快就截取了视频图片
因此采用了Mplayer 来做。
主要代码如下:
using System;
using System.IO;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Threading;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;
namespace CatchVideoImage
{
/// <summary>
/// 提供一个视频截图的基类
/// </summary>
public abstract class VideoImageExcute
{
#region Fields
public string ExeMplayer = @"C:\Program Files\ScreenShots\MPlayer.exe";
public string SaveimageFolder = Application.StartupPath + @"\VideoImage";//截图后保存文件夹
string getLengthArgs = "-nofs -noframedrop -identify -nosound -vo direct3d ";//获取视频长度参数
ManualResetEvent GetLenNotify = new ManualResetEvent(false);//一个获取长度的等待
protected ManualResetEvent notifyDrawChild;//一个绘图等待
protected ManualResetEvent notifySaveImgThumb=new ManualResetEvent(false);//一个绘图等待
protected int imageCount = 10;//默认图片数
protected int spitTime;//影片中的时间间隔
protected string identityImageHander;//递增图片头
protected int flagNo = 1;//图片增加种子标志
protected string mediaPath;//影片路径
int videoLenValue;//影片长度
Font TimeFont=new Font("宋体",30,FontStyle.Bold);//图片中绘时间字体
int TempImageCount = 0;//临时存放图片总数
protected List<string> TimeList = new List<string>();
public ProgressBar ExcuteProgressBar;//进度条
protected bool isReadOlayScreenshots = false;
protected bool SlingThumb = false;//首张略缩截图
#endregion
public abstract string MediaPath{get;set;}
/// <summary>
/// 获取影片长度
/// </summary>
protected int GetVideoLength
{
get
{
CreateMplayer();
Process ps = CreateProcess(GetMediaLength);
ps.Start();
ps.BeginOutputReadLine();
GetLenNotify.WaitOne();
return videoLenValue;
}
}
/// <summary>
/// 图片自增头
/// </summary>
public abstract string IdentityImageHander { get; set; }
/// <summary>
/// 图片时间分隔
/// </summary>
protected abstract int SpitTime { get; set; }
/// <summary>
/// 图片总量
/// </summary>
public abstract int ImageCount { get; set; }
/// <summary>
/// 开始截图拼图
/// </summary>
protected void CupImage()
{
GetLenNotify.WaitOne();
TempImageCount = ImageCount;
flagNo = 1;
TimeList.Clear();
if (ExcuteProgressBar != null)
{
if(isReadOlayScreenshots)
ExcuteProgressBar.Maximum = ImageCount;
else
ExcuteProgressBar.Maximum = ImageCount * 2;
ExcuteProgressBar.Value = 0;
}
DeleteFullFile();
Process cupProcess = CreateProcess(GetTimeJpgArgs(spitTime * flagNo));
cupProcess.Start();
cupProcess.BeginOutputReadLine();
TempImageCount--;
}
/// <summary>
/// 删除所有文件
/// </summary>
protected void DeleteFullFile()
{
if (!Directory.Exists(SaveimageFolder))
Directory.CreateDirectory(SaveimageFolder);
foreach (string item in Directory.GetFiles(SaveimageFolder))
{
File.Delete(item);
}
}
/// <summary>
/// 产生一个可用进程
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public Process CreateProcess(string args)
{
Process ps = new Process();
ps.StartInfo.FileName = ExeMplayer;
ps.StartInfo.RedirectStandardOutput = true;
ps.StartInfo.UseShellExecute = false;
ps.StartInfo.WorkingDirectory = SaveimageFolder;
ps.StartInfo.CreateNoWindow = true;
ps.StartInfo.Arguments = args;
ps.OutputDataReceived += new DataReceivedEventHandler(MoiveDataReceive);
return ps;
}
void MoiveDataReceive(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
ReceiveData(sender, e);
}
}
/// <summary>
/// 一个进程异步接收
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ReceiveData(object sender, DataReceivedEventArgs e)
{
if (e.Data.IndexOf("ID_LENGTH") >= 0)
{
Match math = Regex.Match(e.Data, @"\d+");
videoLenValue = Convert.ToInt32(math.Value);
(sender as Process).Kill();
GetLenNotify.Set();
}
else if (e.Data.IndexOf("Exiting") >= 0 && TempImageCount >= 0)
{
string tempImagePath=SaveimageFolder + @"\00000001.jpg";
if(!SlingThumb)
DrawTimeImage(tempImagePath);
File.Move(tempImagePath, SaveimageFolder + @"\" +IdentityImageHander+flagNo + ".jpg");
if (!SlingThumb)
{
if (ExcuteProgressBar != null)
ExcuteProgressBar.Value = flagNo;
flagNo++;
TempImageCount--;
if (TempImageCount >= 0)
{
Process ps = CreateProcess(GetTimeJpgArgs(flagNo * spitTime));
ps.Start();
ps.BeginOutputReadLine();
Process orgPs = (sender as Process);
if (!orgPs.HasExited)
orgPs.Kill();
}
else
notifyDrawChild.Set();
}
else
notifySaveImgThumb.Set();
}
}
/// <summary>
/// 在图片上绘制时间
/// </summary>
/// <param name="imgPath"></param>
void DrawTimeImage(string imgPath)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
int newWidth;
int newHeight;
using (Bitmap bitmap=new Bitmap(imgPath))
{
using (Graphics g=Graphics.FromImage(bitmap))
{
string timeMsg=GetTime(spitTime * flagNo);
SizeF sf = g.MeasureString(timeMsg, TimeFont);
PointF pf = new PointF(bitmap.Width - sf.Width, bitmap.Height - sf.Height);
g.DrawString(timeMsg, TimeFont, Brushes.White, pf);
TimeList.Add(timeMsg);
newWidth=bitmap.Width;
newHeight=bitmap.Height;
bf.Serialize(ms,bitmap);
ms.Seek(0, SeekOrigin.Begin);
}
}
using (Bitmap newBitMap=(Bitmap)bf.Deserialize(ms))
{
newBitMap.Save(imgPath);
}
}
/// <summary>
/// 获取时间 格式为:hh:mm:ss
/// </summary>
/// <param name="ss"></param>
/// <returns></returns>
protected string GetTime(int ss)
{
string h = ss / 60 > 60 ? (ss / 60 * 2).ToString().Length==1?"0"+(ss / 60 * 2).ToString()
: (ss / 60 * 2).ToString() : "00";
string m = ss / 60 > 60 ? (ss % 60).ToString().Length == 1 ? "0" + (ss % 60).ToString() : (ss % 60).ToString()
: (ss / 60).ToString().Length == 1 ? "0"+(ss / 60).ToString() : (ss / 60).ToString();
string s = ss > 60 ? (ss % 60).ToString().Length == 1 ? "0" + (ss % 60).ToString()
: (ss % 60).ToString() : ss.ToString().Length == 1 ? "0" + ss.ToString() : ss.ToString();
return h + ":" + m + ":" + s;
}
string GetMediaLength
{
get {
return getLengthArgs + "\""+MediaPath+"\"";
}
}
/// <summary>
/// 获图方示
/// </summary>
/// <param name="ss">时间 </param>
/// <returns></returns>
public string GetTimeJpgArgs(int ss)
{
return "-nofs -ss " + ss + " -noquiet -noframedrop -nosound -vo jpeg -frames 1 " + "\"" + MediaPath + "\"";
}
/// <summary>
/// 创建一个Mplayer 文件目录
/// </summary>
public void CreateMplayer()
{
string directoryInfo=Path.GetDirectoryName(ExeMplayer);
if(!Directory.Exists(directoryInfo))
{
Directory.CreateDirectory(directoryInfo);
CreateMplayer();
}else if(!File.Exists(ExeMplayer))
{
CreateMplayerFile();
}
}
/// <summary>
/// 创建Mplayer 文件
/// </summary>
private void CreateMplayerFile()
{
byte[] buffBytes = Properties.Resources.mplayer;
using (FileStream fs = File.Create(ExeMplayer))
{
fs.Write(buffBytes, 0, buffBytes.Length);
}
}
}
}
using System;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace CatchVideoImage
{
/// <summary>
/// 一个图片绘制类
/// </summary>
public class DrawVideoImage:VideoImageExcute
{
public DrawVideoImage(DrawGrid drawGrid,string mediaPath)
{
DrawImageMedia(drawGrid,mediaPath);
SetBottmTimeFont = new Font("黑体", drawGrid.ContentSize / 10, FontStyle.Bold);
SlingThumb = false;
}
private void DrawImageMedia(string mediaPath)
{
if (!File.Exists(mediaPath))
throw new ArgumentException("指定文件不存在!");
MediaPath = mediaPath;
videoLength = base.GetVideoLength;
IdentityImageHander = "VideoImage_";
SpitTime = videoLength / ImageCount;
}
/// <summary>
/// 绘制图片
/// </summary>
/// <param name="drawGrid"></param>
/// <param name="mediaPath"></param>
private void DrawImageMedia(DrawGrid drawGrid, string mediaPath)
{
drawGridObj = drawGrid;
drawGridMap = drawGrid.GetGridBitMap();
if (!File.Exists(mediaPath))
throw new ArgumentException("指定文件不存在!");
this.MediaPath = mediaPath;
videoLength = base.GetVideoLength;
IdentityImageHander = "VideoImage_";
SpitTime = videoLength / drawGrid.ImagePos.Count;
ImageCount = spitTime == 0 ? videoLength : drawGrid.ImagePos.Count;
}
#region Fields
int videoLength;
ManualResetEvent notifyDraw = new ManualResetEvent(false); //一个通知绘制
public int VideoLength
{
get { return videoLength; }
}
DrawGrid drawGridObj;//一个绘图表格对象
Bitmap drawGridMap; //一张可用于绘制的整图
Font SetBottmTimeFont = new Font("黑体",10, FontStyle.Bold);//时间字体
System.Windows.Forms.Timer clockTime=new System.Windows.Forms.Timer();//一个处理用时计时器
public Label info; //信息标签
DateTime dateTime;
Action<Bitmap> thumbComplete;//当视频进入后的一张略缩图
public Action<Bitmap> ThumbComplete
{
get { return thumbComplete; }
set { thumbComplete = value; }
}
#endregion
public override string MediaPath
{
get
{return base.mediaPath;}
set
{base.mediaPath = value;}
}
public bool IsReadOlayScreenshots
{
set {
base.isReadOlayScreenshots = value;
}
}
public ProgressBar ExcuteBar
{
get { return base.ExcuteProgressBar; }
set {
base.ExcuteProgressBar = value;
}
}
public override string IdentityImageHander
{
get
{
return base.identityImageHander;
}
set
{
identityImageHander=value;
}
}
public override int ImageCount
{
get
{
return imageCount;
}
set
{
if (VideoLength < value)
imageCount = VideoLength;
else
imageCount=value;
SpitTime = videoLength / ImageCount;
}
}
public string SaveFolder
{
set
{
base.SaveimageFolder = value;
}
}
protected override int SpitTime
{
get
{
return spitTime;
}
set
{
spitTime = value;
}
}
/// <summary>
/// 开始截拼图
/// </summary>
public void CapImagExcute()
{
dateTime = DateTime.Now;
clockTime.Interval = 500;
clockTime.Start();
clockTime.Tick += new EventHandler(clockTime_Tick);
ThreadPool.QueueUserWorkItem((o) => {
base.notifyDrawChild = notifyDraw;
base.CupImage();
});
ThreadPool.QueueUserWorkItem(
(o)=>{
DrawPictuce();});
}
void clockTime_Tick(object sender, EventArgs e)
{
TimeSpan ts= (DateTime.Now-dateTime);
info.Text = "已用时:" + ts.Hours.ToString() + ":" + ts.Minutes.ToString() + ":" + ts.Seconds;//base.GetTime(totalSS);
}
private void DrawPictuce()
{
notifyDraw.WaitOne();
if (!base.isReadOlayScreenshots)
DrawFullImage();
else
{
clockTime.Stop();
MessageBox.Show("完成");
}
}
//绘制图片到各个标点
private void DrawFullImage()
{
BinaryFormatter bf = new BinaryFormatter();
for (int i = 0; i < ImageCount; i++)
{
ExcuteBar.Value += 1;
string imgPath = SaveimageFolder + @"\" + IdentityImageHander + (i + 1).ToString() + ".jpg";
using (MemoryStream ms = new MemoryStream())
{
try
{
using (Image img = Image.FromFile(imgPath))
{
bf.Serialize(ms, img);
}
File.Delete(imgPath);
using (Graphics grap = Graphics.FromImage(drawGridMap))
{
ms.Seek(0, SeekOrigin.Begin);
using (Image newImg = bf.Deserialize(ms) as Image)
{
grap.DrawImage(newImg, drawGridObj.ImagePos[i].X, drawGridObj.ImagePos[i].Y,
drawGridObj.ContentSize,
drawGridObj.ContentSize - drawGridObj.offSizeH);
SizeF sf = grap.MeasureString(base.TimeList[i], SetBottmTimeFont);
PointF pf = new PointF(drawGridObj.ImagePos[i].X + drawGridObj.ContentSize - sf.Width,
drawGridObj.ImagePos[i].Y + drawGridObj.ContentSize - drawGridObj.offSizeH);
grap.DrawString(base.TimeList[i], SetBottmTimeFont, Brushes.White, pf);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
drawGridMap.Save(SaveimageFolder + @"\NewVideoImage.jpg");
clockTime.Stop();
if (ThumbComplete != null)
thumbComplete(GetThumbBitmap());
MessageBox.Show("成功!");
}
public Bitmap GetThumbBitmap()
{
BinaryFormatter bf = new BinaryFormatter();
Bitmap ReturnBitmap;
using (MemoryStream ms = new MemoryStream())
{
using (Image img = Image.FromFile(SaveimageFolder + @"\NewVideoImage.jpg"))
{
bf.Serialize(ms, img);
ms.Seek(0, SeekOrigin.Begin);
}
//File.Delete(SaveimageFolder + @"\Thumb_1.jpg");
ReturnBitmap = (Bitmap)bf.Deserialize(ms);//new Bitmap(ms);
}
return ReturnBitmap;
}
}
}
using System;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
namespace CatchVideoImage
{
/// <summary>
/// 略缩图类
/// </summary>
public class VideoImageThumb:VideoImageExcute
{
public VideoImageThumb()
{
MediaPath = string.Empty;
IdentityImageHander = "Thumb_";
SpitTime = 1;
ImageCount = 1;
DeleteFullFile();
SlingThumb = true;
}
public void DelFullFile()
{
base.DeleteFullFile();
}
public Bitmap GetThumbBitmap()
{
BinaryFormatter bf = new BinaryFormatter();
Bitmap ReturnBitmap;
using (MemoryStream ms=new MemoryStream())
{
using (Image img = Image.FromFile(SaveimageFolder + @"\Thumb_1.jpg"))
{
bf.Serialize(ms, img);
ms.Seek(0, SeekOrigin.Begin);
}
File.Delete(SaveimageFolder + @"\Thumb_1.jpg");
ReturnBitmap = (Bitmap)bf.Deserialize(ms);
}
return ReturnBitmap;
}
public void WaitSetOne()
{
notifySaveImgThumb.Reset();
notifySaveImgThumb.WaitOne();
}
public override string MediaPath
{
get
{
return base.mediaPath;
}
set
{
base.mediaPath = value;
}
}
public override string IdentityImageHander
{
get
{
return base.identityImageHander;
}
set
{
base.identityImageHander = value;
}
}
protected override int SpitTime
{
get
{
return base.spitTime;
}
set
{
base.spitTime = value;
}
}
public override int ImageCount
{
get
{
return base.imageCount;
}
set
{
base.imageCount = value;
}
}
}
}
using System;
using System.Drawing;
using System.Collections.Generic;
namespace CatchVideoImage
{
public class DrawGrid
{
public DrawGrid(GridRowsCols rowsCols)
{
IntRowsCols(rowsCols);
offsetPointY = (int)((contentSize * serNum)/2f);
offSizeH = (int)(contentSize * serNum);
}
private float serNum = 0.3f;
private int splitLineSize=5;//分隔线大小
private int rows=5;//行数
private int cols=10;//列数
private int contentSize = 500;//分块图片大小
private int offsetPointY;//Y坐标偏移
public int offSizeH;//高度偏移
Bitmap drawBitmap;
Color gridColor = Color.White;
public Color GridColor
{
get { return gridColor; }
set { gridColor = value; }
}
List<Point> imagePos = new List<Point>();
public List<Point> ImagePos
{
get { return imagePos; }
set { imagePos = value; }
}
public int ContentSize
{
get { return contentSize; }
set {
contentSize = value;
offsetPointY = (int)((contentSize * serNum) / 2f);
offSizeH = (int)(contentSize * serNum);
}
}
public int SplitLineSize
{
get { return splitLineSize; }
set { splitLineSize = value; }
}
public Bitmap GetGridBitMap()
{
Size size= GetBitmapSize(cols, rows);
int bitmapWidth =size.Width;
int bitmapHeight = size.Height;
drawBitmap = new Bitmap(bitmapWidth, bitmapHeight);
ImagePos.Clear();
using (Graphics g = Graphics.FromImage(drawBitmap))
{
g.Clear(Color.Gray);
DrawGridView(g, cols, rows,1);
}
return drawBitmap;
}
/// <summary>
/// 递归调用绘线
/// </summary>
/// <param name="bitmapG"></param>
/// <param name="col"></param>
/// <param name="row"></param>
void DrawGridView(Graphics bitmapG, int col, int row,int rowOffset)
{
col= col < 0 ? 0 : col;
row = row < 0 ? 0 : row;
Size size= GetBitmapSize(col,row);
int y=size.Height;
int x = size.Width;
using (Pen p=new Pen(new SolidBrush(gridColor),splitLineSize))
{
bitmapG.DrawLine(p, 0, y -G_Int , drawBitmap.Width, y - G_Int);//绘横线
bitmapG.DrawLine(p, x - G_Int, 0, x - G_Int, drawBitmap.Height);//绘纵线
}
if (row > 0)
{
for (int i = 1; i <= cols; i++)//添加点
{
Point orgPoint = new Point(GetBitmapSize(i, i).Width - G_Int - G_Int,
GetBitmapSize(i, rowOffset).Height - G_Int - G_Int);
Size sizePoint = new Size(contentSize-1 , contentSize - offsetPointY);
Point newPoint = Point.Subtract(orgPoint, sizePoint);
ImagePos.Add(newPoint);
}
}
if (col == 0 && row == 0)
return;
--col;
--row;
rowOffset++;
DrawGridView(bitmapG, col, row,rowOffset);
}
/// <summary>
/// 分隔线
/// </summary>
int G_Int
{
get
{
double d = splitLineSize / 2d;
return (int)Math.Ceiling(d);
}
}
/// <summary>
/// 获取高宽度
/// </summary>
/// <param name="col"></param>
/// <param name="row"></param>
/// <returns></returns>
Size GetBitmapSize(int col,int row)
{
int x = col * contentSize + col * splitLineSize +splitLineSize;
int y= row * contentSize + row * splitLineSize + splitLineSize;
Size size = new Size(x,y);
return size;
}
void IntRowsCols(GridRowsCols rowsCols)
{
switch (rowsCols)
{
case GridRowsCols.Rows_18_Cols_25:
rows = 18;
cols = 25;
break;
case GridRowsCols.Rows_18_Cols_23:
rows = 18;
cols = 23;
break;
case GridRowsCols.Rows_17_Cols_22:
rows = 17;
cols = 22;
break;
case GridRowsCols.Rows_16_Cols_20:
rows = 16;
cols = 20;
break;
case GridRowsCols.Rows_15_Cols_19:
rows = 15;
cols = 19;
break;
case GridRowsCols.Rows_15_Cols_17:
rows = 15;
cols = 17;
break;
case GridRowsCols.Rows_13_Cols_15:
rows = 13;
cols = 15;
break;
case GridRowsCols.Rows_12_Cols_15:
rows = 12;
cols = 15;
break;
case GridRowsCols.Rows_10_Cols_15:
rows = 10;
cols = 15;
break;
case GridRowsCols.Rows_8_Cols_12:
rows = 8;
cols = 12;
break;
case GridRowsCols.Rows_6_Cols_11:
rows = 6;
cols = 11;
break;
case GridRowsCols.Rows_5_Cols_10:
rows = 5;
cols = 10;
break;
case GridRowsCols.Rows_5_Cols_6:
rows = 5;
cols = 6;
break;
case GridRowsCols.Rows_3_Cols_5:
rows = 3;
cols = 5;
break;
case GridRowsCols.Rows_2_Cols_5:
rows = 2;
cols = 5;
break;
default:
rows = 2;
cols = 3;
break;
}
}
}
}
上张效果图
- 利用Mplayer 实现视频连拍
- 实现Camera连拍功能
- IOS 实现Camera连拍功能
- iOS调用相机实现连拍
- Android自定义相机实现N连拍
- 利用python批量下载美拍视频
- 利用python 批量下载美拍视频
- 美拍、秒拍短视频SDK功能实现
- Android如何调用拍照程序实现连拍
- Android相机连续拍照实现连拍功能
- iOS自定义相机实现拍照和连拍
- 侧按键长按三秒后实现连拍 短按拍照
- android 快速连拍
- Camera 连拍,画中画
- camera 2 连拍
- D90拍的视频
- 微拍视频下载
- 关于爱拍(拍视频)
- Excel VBA代码学习
- git 常用命令
- 镜像主体显示断开处理
- 运行jar
- 如何查看oracle sql执行计划
- 利用Mplayer 实现视频连拍
- C#的office文档操作
- 高级指针
- rman异机数据库迁移步骤
- 判断字符串是否是数字
- pku2418水题map--自己写BST
- 推荐7款国产的在线HTML编辑器
- oracle权限
- Grub 图形化的启动管理器