C#實(shí)現(xiàn)語(yǔ)音視頻錄制-附demo源碼
在很多語(yǔ)音視頻軟件系統(tǒng)中,經(jīng)常有將實(shí)時(shí)的音頻或視頻錄制為文件保存到磁盤(pán)的需求,比如,視頻監(jiān)控系統(tǒng)中錄制監(jiān)控到的視頻、視頻會(huì)議系統(tǒng)中錄制整個(gè)會(huì)議的過(guò)程、語(yǔ)音通話系統(tǒng)中錄制完整的對(duì)話內(nèi)容、等等?!?/p>
MFile組件(Oraycn.MFile.dll)是傲瑞實(shí)用組件之一,它可以將原始的語(yǔ)音數(shù)據(jù)和視頻數(shù)據(jù)按照指定的格式進(jìn)行編碼,并將它們寫(xiě)入到視頻文件(如.mp4)中。
一.緣起
最近正在做的一個(gè)網(wǎng)絡(luò)招聘平臺(tái)的項(xiàng)目,其中有一個(gè)模塊是這樣的,應(yīng)聘者可以通過(guò)該系統(tǒng)的客戶端錄制自己的視頻(自我介紹)上傳到服務(wù)器,而后,招聘者會(huì)在合適的時(shí)候?yàn)g覽這些應(yīng)聘者的視頻。該模塊涉及到的主要技術(shù)就是語(yǔ)音視頻錄制技術(shù),它需要把從麥克風(fēng)采集到的語(yǔ)音數(shù)據(jù)和從攝像頭采集到的視頻數(shù)據(jù)編碼并寫(xiě)到.mp4文件中。
要完成這些功能,具體來(lái)說(shuō),需要解決如下幾個(gè)技術(shù)問(wèn)題:
(1)麥克風(fēng)數(shù)據(jù)采集
(2)攝像頭數(shù)據(jù)采集
(3)音頻數(shù)據(jù)編碼
(4)視頻數(shù)據(jù)編碼
(5)將編碼后的數(shù)據(jù)按.mp4文件格式寫(xiě)入到文件容器中。
(6)保證音頻視頻播放的同步。
二.Demo實(shí)現(xiàn)
如果要從頭開(kāi)始一步步解決這些問(wèn)題,將是非常艱難的挑戰(zhàn)。幸運(yùn)的是,我們可以通過(guò)已有組件的組合來(lái)實(shí)現(xiàn)這些功能,語(yǔ)音視頻數(shù)據(jù)的采集我們可以借助OMCS框架完成,后續(xù)的語(yǔ)音視頻編碼并生成mp4文件,我們可以借助MFile組件完成。為了更方便地講解,這里我們將給出一個(gè)具體的demo,它可以錄制從本地?cái)z像頭和本地麥克風(fēng)采集的數(shù)據(jù)并生成mp4文件。demo運(yùn)行的截圖如下所示:
接下來(lái),我們來(lái)說(shuō)說(shuō)在這個(gè)demo中是如何一個(gè)個(gè)解決上述問(wèn)題的。
1.語(yǔ)音數(shù)據(jù)采集
我們可以使用OMCS的MicrophoneConnector組件連接到自己的麥克風(fēng)設(shè)備,這樣,揚(yáng)聲器就會(huì)播放采集到的語(yǔ)音,而且,我們可以通過(guò)通過(guò)IMultimediaManager暴露的AudioPlayed事件,來(lái)捕獲正在播放的語(yǔ)音數(shù)據(jù)。
2.視頻數(shù)據(jù)采集
同樣的,我們可以使用CameraConnector控件連接到自己的攝像頭設(shè)備,然后,定時(shí)器每隔100ms(假設(shè)幀頻為10fps)調(diào)用其GetCurrentImage方法獲得正在繪制的Bitmap。
3.后續(xù)步驟
后續(xù)的4步都可以交由MFile組件搞定,我們大概看一下MFile組件中VideoFileMaker類的簽名,就知道怎么做了:
MFile 結(jié)構(gòu)
對(duì)于使用者而言,MFile組件中的主要類的結(jié)構(gòu)圖如下所示:
其中,AudioFileMaker用于生成音頻文件、SilenceVideoFileMaker用于生成無(wú)聲的視頻文件、而VideoFileMaker用于生成既有聲音又有圖像的普通視頻文件。這三個(gè)類都從基類BaseMaker繼承,它們的使用方式也是一致的。接下來(lái),我們僅僅詳細(xì)講解VideoFileMaker類的使用,SilenceVideoFileMaker 和 AudioFileMaker的使用方法可以類推之。
下面是VideoFileMaker類的public方法的簽名
代碼如下:
public class VideoFileMaker :IDisposable { /// <summary> /// 初始化視頻文件。 /// </summary> /// <param name="filePath">文件路徑</param> /// <param name="videoCodec">視頻編碼格式</param> /// <param name="videoWidth">視頻寬度</param> /// <param name="videoHeight">視頻高度</param> /// <param name="videoFrameRate">幀頻</param> /// <param name="audioCodec">音頻編碼格式</param> /// <param name="audioSampleRate">音頻采樣率?!咀ⅲ翰蓸游粩?shù)必須為16位】</param> /// <param name="audioChannelCount">聲道數(shù)</param> /// <param name="autoSyncToAudio">如果是實(shí)時(shí)錄制,則可傳入true,以音頻為基準(zhǔn)進(jìn)行同步。</param> void Initialize(string filePath, VideoCodecType videoCodec, int videoWidth, int videoHeight, int videoFrameRate, AudioCodecType audioCodec, int audioSampleRate, int audioChannelCount, bool autoSyncToAudio); /// <summary> /// 添加音頻幀。 /// </summary> void AddAudioFrame(byte[] audioframe); /// <summary> /// 添加視頻幀。如果autoSyncToAudio開(kāi)啟,則自動(dòng)同步到音頻。 /// </summary> void AddVideoFrame(Bitmap frame); /// <summary> /// 添加視頻幀。 /// </summary> /// <param name="frame">視頻幀</param> /// <param name="timeStamp">離開(kāi)始時(shí)的時(shí)間長(zhǎng)度</param> void AddVideoFrame(Bitmap frame, TimeSpan timeStamp); /// <summary> /// 關(guān)閉視頻文件。 /// </summary> /// <param name="waitFinished">如果還有幀等待寫(xiě)入文件,是否等待它們?nèi)繉?xiě)入文件。</param> void Close(bool waitFinished); }
首先調(diào)用Initialize方法完成初始化,然后,循環(huán)調(diào)用AddAudioFrame和AddVideoFrame方法,當(dāng)完成視頻錄制時(shí),則調(diào)用Close方法,即可。很簡(jiǎn)單,不是嗎?
4.主要代碼
首先,我們以aa01用戶登錄到OMCS服務(wù)器,然后,在拖拽一個(gè)CameraConnector控件和一個(gè)MicrophoneConnector組件到主窗體上,然后,讓它們都連到自己的攝像頭和麥克風(fēng)。
this.multimediaManager = MultimediaManagerFactory.GetSingleton(); this.multimediaManager.Initialize("aa01", "", "127.0.0.1", 9900); this.cameraConnector1.BeginConnect("aa01"); this.microphoneConnector1.BeginConnect("aa01");
接下來(lái),我們初始化VideoFileMaker組件:
this.videoFileMaker.Initialize("test.mp4", VideoCodecType.H264, this.multimediaManager.CameraVideoSize.Width, this.multimediaManager.CameraVideoSize.Height, 10, AudioCodecType.AAC, 16000, 1, true); this.timer = new System.Threading.Timer(new System.Threading.TimerCallback(this.Callback), null ,0, 100); this.multimediaManager.AudioPlayed += new ESBasic.CbGeneric<byte[]>(multimediaManager_AudioPlayed);
參數(shù)中設(shè)定,使用h.264對(duì)視頻進(jìn)行編碼,使用aac對(duì)音頻進(jìn)行編碼,并生成mp4格式的文件。然后,我們可以通過(guò)OMCS獲取實(shí)時(shí)的音頻數(shù)據(jù)和視頻數(shù)據(jù),并將它們寫(xiě)到文件中。
void multimediaManager_AudioPlayed(byte[] audio) { this.videoFileMaker.AddAudioFrame(audio); } private void Callback(object state) { Bitmap bm = this.cameraConnector1.GetCurrentImage(); this.videoFileMaker.AddVideoFrame(bm); }
當(dāng)想結(jié)束錄制時(shí),則調(diào)用Close方法:
this.videoFileMaker.Close(true);
這樣錄制生成的test.mp4文件就可以直接用我們的QQ影音或暴風(fēng)影音來(lái)播放了。
更多細(xì)節(jié),請(qǐng)查看demo源碼。
三.Demo下載
2014.11.26 現(xiàn)在錄制本地的語(yǔ)音、視頻、屏幕的最好的方案是MCapture + MFile,而不是通過(guò)OMCS繞一大圈,相應(yīng)的Demo源碼下載:Oraycn.RecordDemo.rar 。
當(dāng)然,如果是遠(yuǎn)程錄制語(yǔ)音、視頻、屏幕,最好的方案是OMCS + MFile。
以上就是本文針對(duì)C#實(shí)現(xiàn)語(yǔ)音視頻錄制-附demo源碼的全部?jī)?nèi)容,希望大家喜歡。
- C#使用DirectX.DirectSound播放語(yǔ)音
- C#實(shí)現(xiàn)文本轉(zhuǎn)語(yǔ)音功能
- C#實(shí)現(xiàn)語(yǔ)音播報(bào)功能
- C# windows語(yǔ)音識(shí)別與朗讀實(shí)例
- c# 實(shí)現(xiàn)語(yǔ)音聊天的實(shí)戰(zhàn)示例
- c# 實(shí)現(xiàn)語(yǔ)音合成
- c# 開(kāi)發(fā)語(yǔ)音識(shí)別程序
- C#基于UDP實(shí)現(xiàn)的P2P語(yǔ)音聊天工具
- C#中調(diào)用SAPI實(shí)現(xiàn)語(yǔ)音合成的2種方法
- C#實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音功能
相關(guān)文章
C#實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳下載的方法
這篇文章主要介紹了C#實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳下載的方法,涉及網(wǎng)絡(luò)文件操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05C#中前臺(tái)線程和后臺(tái)線程的區(qū)別與聯(lián)系
這篇文章主要介紹了C#中前臺(tái)線程和后臺(tái)線程的區(qū)別與聯(lián)系,本文先講解了它們的區(qū)別,然后給出了一個(gè)例子來(lái)驗(yàn)證這些區(qū)別,需要的朋友可以參考下2015-06-06C#設(shè)置開(kāi)機(jī)啟動(dòng)項(xiàng)、取消開(kāi)機(jī)啟動(dòng)項(xiàng)
這篇文章主要介紹了C#設(shè)置開(kāi)機(jī)啟動(dòng)項(xiàng)、取消開(kāi)機(jī)啟動(dòng)項(xiàng),本文通過(guò)修改注冊(cè)實(shí)現(xiàn),并給出操作代碼,需要的朋友可以參考下2015-06-06c#中單例類與靜態(tài)類的區(qū)別以及使用場(chǎng)景
這篇文章主要給大家介紹了關(guān)于c#中單例類與靜態(tài)類的區(qū)別以及使用場(chǎng)景的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01