不得不說(shuō)FFMPEG真是個(gè)神奇的玩意,所接觸的部分不過(guò)萬(wàn)一。網(wǎng)上有個(gè)很火的例子是c++方面的,當(dāng)然這個(gè)功能還是用c++來(lái)實(shí)現(xiàn)比較妥當(dāng)。
然而我不會(huì)c++
因?yàn)槲业墓δ苄枨蟊容^簡(jiǎn)單,只要實(shí)現(xiàn)基本的錄制就可以了,其實(shí)就是一句命令的事
先來(lái)代碼:RecordHelper類(lèi)
using
System;
using
System.Collections.Generic;
using
System.Diagnostics;
using
System.IO;
using
System.Linq;
using
System.Text;
using
System.Threading.Tasks;
using
Microsoft.DirectX;
using
Microsoft.DirectX.DirectSound;
using
System.Runtime.InteropServices;
namespace
ClassTool
{
public
class
RecordHelper
{
#region
模擬控制臺(tái)信號(hào)需要使用的api
[DllImport(
"
kernel32.dll
"
)]
static
extern
bool
GenerateConsoleCtrlEvent(
int
dwCtrlEvent,
int
dwProcessGroupId);
[DllImport(
"
kernel32.dll
"
)]
static
extern
bool
SetConsoleCtrlHandler(IntPtr handlerRoutine,
bool
add);
[DllImport(
"
kernel32.dll
"
)]
static
extern
bool
AttachConsole(
int
dwProcessId);
[DllImport(
"
kernel32.dll
"
)]
static
extern
bool
FreeConsole();
#endregion
//
ffmpeg進(jìn)程
static
Process p =
new
Process();
//
ffmpeg.exe實(shí)體文件路徑
static
string
ffmpegPath = AppDomain.CurrentDomain.BaseDirectory +
"
ffmpeg\\ffmpeg.exe
"
;
///
<summary>
///
獲取聲音輸入設(shè)備列表
///
</summary>
///
<returns>
聲音輸入設(shè)備列表
</returns>
public
static
CaptureDevicesCollection GetAudioList()
{
CaptureDevicesCollection collection
=
new
CaptureDevicesCollection();
return
collection;
}
///
<summary>
///
功能: 開(kāi)始錄制
///
</summary>
public
static
void
Start(
string
audioDevice,
string
outFilePath)
{
if
(File.Exists(outFilePath))
{
File.Delete(outFilePath);
}
/*
轉(zhuǎn)碼,視頻錄制設(shè)備:gdigrab;錄制對(duì)象:桌面;
* 音頻錄制方式:dshow;
* 視頻編碼格式:h.264;
*/
ProcessStartInfo startInfo
=
new
ProcessStartInfo(ffmpegPath);
startInfo.WindowStyle
=
ProcessWindowStyle.Normal;
startInfo.Arguments
=
"
-f gdigrab -framerate 15 -i desktop -f dshow -i audio=\"
"
+ audioDevice +
"
\" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -acodec libmp3lame \"
"
+ outFilePath +
"
\"
"
;
p.StartInfo
=
startInfo;
p.Start();
}
///
<summary>
///
功能: 停止錄制
///
</summary>
public
static
void
Stop()
{
AttachConsole(p.Id);
SetConsoleCtrlHandler(IntPtr.Zero,
true
);
GenerateConsoleCtrlEvent(
0
,
0
);
FreeConsole();
}
}
}
開(kāi)始那幾個(gè)api接口是用來(lái)模擬ctrl+c命令的。本來(lái)以為在停止錄制的時(shí)候直接kill掉進(jìn)程就好,結(jié)果導(dǎo)致生成的視頻文件直接損壞了。手動(dòng)使用ffmpeg.exe的時(shí)候發(fā)現(xiàn)ctrl+c可以直接結(jié)束錄制并且不會(huì)損壞視頻文件,于是采用這種方法,在點(diǎn)擊停止按鈕時(shí)模擬ctrl+c來(lái)退出ffmpeg。
ffmpeg的命令參數(shù)里,gdigrab是ffmpeg內(nèi)置的屏幕錄制設(shè)備,但是這個(gè)設(shè)備不能同時(shí)采集音頻,于是又用到了后面的dshow。這里有個(gè)問(wèn)題很奇怪,用ffmpeg獲取音頻設(shè)備列表時(shí),設(shè)備的名稱如果超過(guò)31個(gè)字符的話會(huì)被截?cái)啵羰菍⑼暾脑O(shè)備名傳到參數(shù)里則無(wú)法進(jìn)行音頻采集,只能將截?cái)嗟脑O(shè)備名稱傳進(jìn)去,不知道為什么……
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

