一個很全面的forum
http://bbs.chinavideo.org/forumdisplay.php?fid=10
中文網站
http://www.ffmpeg.com.cn/index.php/%E9%A6%96%E9%A1%B5
前一段時間做視頻轉換,在做的過程中我遇到了很多問題,把自己的經驗寫一下,共大家參考:
用戶上傳的視頻我主要愛
格式:
ffmpeg [[輸入文件選項]- i 輸入文件名] {[輸入文件選項] 輸出文件名}
主要選項:
-L 顯示ffmpeg的版權說明
-h 顯示幫助
-version 顯示版本
-formats 顯示支持的文件格式,編碼和協議
-f 格式名 強制使用格式
-img 文件格式名 強制使用片格式
-i 文件名 待轉換文件名字
-y 覆蓋同名輸出文件
-t 時間 設置影片時間長度
-fs 最大尺寸 設置文件的最大尺寸
-ss 時間點 設置開始轉換的時間點
-title 文字 設置標題
-author 文字 設置作者
-copyright 文字 設置版權聲明
-comment 文字 設置備註
視頻選項:
-b 比特率 設置文件比特率 (單位是kbit/s)
-r 速度 楨速度 (Hz value)
-s 大小 設置大小,寬乘高
-newvideo 在現在的視頻流後面加入信的視頻流
音頻選項:
-aframes 數字 設置轉換多少楨(frame)的音頻
-ab bitrate 設置音樂的比特率(單位:kbit/s)
-aq 質量 這隻音頻質量 (指定編碼)
-ar 採樣率 設置音頻採樣率 (單位:Hz)
-ac 聲道數字 設置聲道數
-an 取消音頻
-acodec 編碼 強制音頻 編碼 ('copy' to copy stream)
-vol volume 改變音量 (256爲普通)
-newaudio 追加音樂
是這樣的,現在得接到任務得進行一個視頻共享網站的視頻上傳轉換技術,我在google裏面一下就找了ffmpeg,經過一天的研究終於用java+ffmpeg代碼寫了個小小的轉換程序,但是現在有了點變動要求我利用ffmpeg的源代碼進行編譯,也就說要使用動態連接庫了,可以前從來沒接觸過,我一直做的是java的啊,對VC和C#什麼的一點都不瞭解,所以請給位高手,大俠們提供一個在java開發環境下使用ffmepg開發視頻共享網站上傳視頻轉換技術的思路啊,我的開發環境下是widowsxp的啊。謝謝啊,現在真的是救命啊!:'(
轉換的話...JAVA一樣可以調用FFMPEG的EXE程序吧...
恩,前天剛用java做過了一個小程序用的就是ffmpeg.exe文件的,轉換的幾種文件都成功了,現在的關鍵是在VC下對COM的開發了,用JAVA能開發嗎?因爲我想網站的流量可能會很大所以用exe文件應該不怎麼行的,只有封裝了dll文件纔會更好的支持,還有想請教下,想對ffmpeg的源代碼和思想進行下研究,你能提供的方法嗎?我看過貼子您也做過視頻網站開發的能提供點經驗嗎?謝謝
爲什麼這麼說呢?
不瞞大家啊,這是我畢業的第一份工作,我想做好啊,並切會努力的學習的,希望大家多多的幫助啊。謝謝啦。:)
問下admin啊,編寫的com是不是要編寫實現視頻轉換功能的代碼啊?能不能給點代碼參考下啊?
我不知道我這樣想的對不對,但我還是說下哈,在第一個ConvertVideo.java的時候,ffmpeg.exe文件只有放在ConvertVideo.java相同的目錄下才能成功的,我不知道這是什麼原因,但是我覺得在一個項目中不能每次都要去用 ... [/quote]
其實把FFMPEG封裝成COM調用...跟直接調用FFMPEG.EXE一樣...
我不知道JAVA能不能調用絕對路徑的外部程序,但覺得應該可以...不需要一定放在跟JAVA文件同目錄下...
封裝成COM組件來用,也得建立一條獨立線程來執行...不可能阻塞主線程的...而且也不可能把信息實時反饋給用戶...因爲你做的是網站...不是本地程序...
我用C#也是一樣的用FFMPEG.EXE...感覺跟用COM沒多大分別...
問下admin啊,編寫的com是不是要編寫實現視頻轉換功能的代碼啊?能不能給點代碼參考下啊? [/quote]
代碼是沒有的...當初我也碰到過同樣的問題...不過原因跟你有點不一樣而已...
你可以直接用JAVA調用DLL(可以的話),這樣做就要把處理邏輯用JAVA來寫...
你也可以把整個FFMPEG封裝成一個COM...這個COM提供2個接口...1個輸入,1個輸出...然後JAVA調用...
建議:你編寫一個獨立的轉換系統,支持多線程、批處理……,可獨立運行的,然後你的java程序通過一定的方式(如通過數據庫交換)向前面說的獨立轉換系統提交轉換任務,轉換系統接收到新的轉換後,開始轉換,同時寫入轉換進度到數據庫中,這時,你的java程序也可以從數據庫中獲取實時的轉換進度了,轉換系統轉換完成之後,把結果也寫入數據庫,這樣,你的java程序也就知道轉換完成了。這樣做的好處是,可以實現分佈式處理、多服務器並行處理、系統的負載均衡處理等,優勢還是很明顯的。
可以很明確說,大型一點的視頻網站,都不是用戶上傳一個文件就馬上在WEB進程中轉換的,而是有一套如我上面所說的轉換系統,而且轉換不一定是在WEB發佈的服務器上進行的,有專門的轉換服務器,:)
admin 大俠啊,你給我思路我基本是懂了,可似乎更難了啊?!:( ~~
所以我現在想不這樣考慮了,我想再寫一個dll文件,直接加載ffmpeg中的main方法,去執行我的需求,你看怎麼樣啊?還有我想讀下代碼該怎麼去理解啊?你有相關的看代碼的幫助文檔嗎?我現在會很努力的去學習C了了,給點資料哈,再次表示謝謝啦~~~~~~~~~好人啦~~~~~~`:) :victory:
我現在做的那個項目就有你這樣的問題...
我也是直接寫了一個類...用asp.net調用外部程序(ffmpeg.exe),轉換,然後獲取返回的信息...來寫到數據庫...
而這個類是用一條新的進程來執行的...網站主線程不需要等待...
而且這個類還會自動掃描數據庫...只要後用戶上傳後,調用了這個類...他就會掃描一遍數據庫,發現沒轉換的,循環轉換...
這樣轉換和網站就可以脫離開了...
而我也明白你的意思...你是想做成一個DLL或者COM...讓網站主線程直接調用...把信息實時反饋給用戶...
但這是不太可能的...因爲網站不是本地程序...不可能跟外殼(網站就是指客戶端頁面,本地程序就是指窗體)實時交互...就算用ajax也不行...因爲後臺處理有一個併發的問題...
我公司一臺服務器,用最新架構的至強3.0CPU...也最多能並行運行10個左右的FFMPEG...超過了就會卡機...
所以WEB的後臺轉換必須是用隊列來實現...一次轉一個...這是最理想的...當然...這又要用到線程阻塞之類的東西...這就沒辦法幫你了...呵呵...
“我也是直接寫了一個類...用asp.net調用外部程序(ffmpeg.exe),轉換,然後獲取返回的信息...來寫到數據庫...
而這個類是用一條新的進程來執行的...網站主線程不需要等待...
而且這個類還會自動掃描數據庫...只要後用戶上傳後,調用了這個類...他就會掃描一遍數據庫,發現沒轉換的,循環轉換...
這樣轉換和網站就可以脫離開了...”
能具體說下思想嗎?或則可能的話給我點源代碼,順便讓我學學習c方面的餓知識啊。:handshake
“我也是直接寫了一個類...用asp.net調用外部程序(ffmpeg.exe),轉換,然後獲取返回的信息...來寫到數據庫...
而這個類是用一條新的進程來執行的...網站主線程不需要等待...
而且這個類還會自動掃描數據庫...只要 ... [/quote]
我是用C#寫的...代碼有啊...這論壇就有...
[url=http://bbs.chinavideo.org/viewthread.php?tid=2326&extra=page%3D1]http://bbs.chinavideo.org/viewthread.php?tid=2326&extra=page%3D1[/url]
那是C#寫的...不知道你看得明白不...
然後調用轉換類(或者方法)...掃描數據庫...做個SELECT就行了...得出數據集...
這要看你的思路了...
1.可以把全部未轉換的select出來,然後用for(XXX)來循環這個數據集
2.用select top 1 加while來掃描...
第一種方法就安全一點,但在這個類(或者方法)執行(數據集取出來後)過程,再有用戶上傳,也不會被加入轉換隊列,需要等當前轉換隊列完成後,再有用戶上傳,纔會被加到轉換隊列...
第二種方法就比較危險一點,畢竟是用while,只要中間邏輯出現任何錯誤,就有可能出現死循環...但是用while和select top 1的話,轉換隊列是非常靈活的...是取一條,轉一個...也就是說,只要這個while沒完成(就是說數據庫中還有沒被轉換的,包括轉換開始後才增加的數據),他都會調出來加到隊列轉換...相對實時一點...
上面說的是數據庫掃描的思路...
下面說說轉換的安全性...
視頻轉換佔用CPU嚴重人盡皆知,這個就沒啥好說的...所以我推薦不併發...每次只轉換1個視頻...
那麼你用開發語言(JAVA也好,C#也好)調用外部程序(ffmpeg.exe)的時候...記得...一定要等待進程結束...不然的話...等着死機吧...我試過做一個while+select top1的轉換隊列系統...忘記了加上等待進程結束的語句...結果FFMPEG那個線程被運行了上百條...但其實我數據庫只有1條未轉換記錄...但是隻要沒轉換完成,他就不會把數據庫的記錄改寫(改成已轉換),所以WHILE不斷的建立新線程來執行...
調用外部程序,系統會分配一條獨立的線程序,這裏只要加上等待線程結束的語句就好了...
另外,調用整個類(或者方法),也必須開一條單獨的線程序,而且只能運行1個這樣的線程序...
舉個例...你的網站肯定不會只有1個別用戶訪問...那麼的話...這個類(或者方法)有可能被調用多次...那麼如果不限制執行這個類(或者方法)的數量,那麼就會產生多個類(或者方法)的鏡像...同時執行...同時掃描數據庫,同時開1條FFMPEG進程來轉換同1份文件...最後的結果也是消耗無謂的資源...導致服務器掛掉...這也很好的說明web站和本地程序開發的很大不同...一個併發量問題...
所以呢...這整個類(或者方法)你也要做保護裝置...你可以用1個全局變量來保存一個狀態...例如這個全局變量爲status...那麼每當這個類(或者方法)開始執行,就把status改成1...然後在這個類(或者方法)外部再加一個判斷:
if(status == 1) return;
這樣就是一個簡單的保護了...
複雜一點的方法呢...就是用一條線程來執行這個類(或者方法)...用阻塞來防止被多次運行這個類(或者方法)...至於實現的辦法...每種語言都不同...你自己找找方法吧...
這是我將要使用在我項目上的思路...呵呵...
最後,告誡一句...程序員...只有想不到,沒有做不到...多多發散自己的思維...對你以後工作會有很大幫助...
我看了你寫的思路,恩,收穫很大的。這可是說真的啊。我現在呢,有了兩種想法,一種是在在客戶端,一種是在服務器端去處理轉換的。呵呵,現在只是在構想中。
我絕對支持你說的那句話,程序員....只有想不到,沒有做不到。我會加油的。呵呵~~~~~~
由於對軟件編寫不熟,所以我用的是服務器端轉換..等上傳完成後,直接返回用戶信息.其他都交給服務器處理..還沒測試過併發的問題....
想問下,你們怎麼測試ffmpeg轉換的併發問題的?
我看了你寫的思路,恩,收穫很大的。這可是說真的啊。我現在呢,有了兩種想法,一種是在在客戶端,一種是在服務器端去處理轉換的。呵呵,現在只是在構想中。
我絕對支持你說的那句話,程序員....只有想不到,沒有 ... [/quote]
客戶端轉可以...
但是用戶會產生不好的心理...
誰叫客戶都是上帝...
而且客戶端轉會產生很多意想不到的問題...超出你的控制範圍...
在服務器端轉呢...出錯了,還有挽救的餘地.