2009-12-02 56 views
11

有一點背景,我被賦予修復一些「小」錯誤並維護這個解決方案以在我們的應用的兩個實例之間通過網絡流式傳輸視頻的任務。這個解決方案是由不再在這裏的人編寫的,所以代碼中有一些神祕的地方,以及一些非常有趣的陷阱。該解決方案使用ffmpeg編寫,其中編寫的C++代碼用於封裝與編碼/解碼相關的代碼以及一些流式代碼。然後用SWIG包裝這個C++,以便它可以與C#互操作,並將視頻幀傳遞到使用位於WPF控件中的VideoRendererElement呈現的位置。幀傳遞的主要原因是因爲我們有一些我們需要發送視頻數據的自定義協議,並且這些協議是使用C#編寫的,因此在傳輸視頻幀時,我們將它們包裝在我們自己的數據包中,並通過線路發送出去。這個解決方案的工作原理和我們可以使用我們的自定義協議流式傳輸視頻,儘管這是一個噩夢來維護和使用。如何使用C#編碼/解碼視頻?

我的問題是否有更好的方法來解決這個問題?我正在尋找方法,使用視頻數據(使用C#)在較低級別上工作,以便我可以將視頻幀封裝到我們自己的數據包中,並將它們發送出去,並能夠接收並重建視頻另一邊。 ffmpeg似乎是常見的解決方案,但我遇到了很多與它有關的問題以及我認爲是問題的GPL/LGPL問題。

我期望實現的基本流程, 視頻文件 - >編碼 - >封裝在數據包中 - >在協議X上通過導線發送 - >從數據包獲取視頻數據 - >解碼 - >渲染/保存到磁盤

+0

LGPL爲什麼是你的問題?即使您的應用程序適用於商業客戶,也不應該成爲問題。 – 2009-12-02 18:39:35

+0

可能重複:http://gackoverflow.com/questions/271003/anyone-know-of-a-set-of-c-bindings-for-ffmpeg – 2009-12-02 18:52:17

+0

GPL/LGPL的東西是由另一個同事提出的,但他們聽起來好像我們正在使用ffmpeg及其依賴庫的方式打破許可證。至於重複的帖子,我試圖擺脫ffmpeg如果可能的話,尖銳的ffmpeg似乎並不像它的工作或它已被支持了。 – 2009-12-02 19:01:41

回答

0

你可能試着看的是SharpFFmpeg。雖然您可能能夠看到他們如何編寫自己的封裝,但您可以編寫自己的封裝,或瞭解如何解決當前的解決方案。

編輯:

有一個類似的包裝稱爲ffmpeg-sharp在code.google.com上,它採用了LGPL - 你可以在商業應用中使用。我懷疑這兩種包裝紙的效果都差不多,儘管SharpFFmpeg較舊,可能更成熟。

2

我曾經用ffmpeg把各種各樣的麻煩包裹進一個DLL中。我的視頻項目非常簡單 - 我只需要轉換器從WMV獲取單個縮略圖。

在嘗試了您所描述的之後,我的解決方案是將ffmpeg.exe二進制文件作爲外部庫複製到我的項目中。這也整齊地得到周圍的任何代碼許可證的問題,據我所知......

 Guid temp = Guid.NewGuid(); 

     // just throw our ffmpeg commands at cmd.exe 
     System.Diagnostics.ProcessStartInfo psi = 
      new System.Diagnostics.ProcessStartInfo("cmd.exe"); 

     psi.WorkingDirectory = Page.MapPath(@"~\Lib\ffmpeg.rev12665"); 

     psi.UseShellExecute = false; 
     psi.RedirectStandardError = true; 
     psi.RedirectStandardOutput = true; 
     psi.RedirectStandardInput = true; 

     System.Diagnostics.Process ps = System.Diagnostics.Process.Start(psi); 

     StreamReader outputReader = ps.StandardOutput; 
     StreamReader errorReader = ps.StandardError; 
     StreamWriter inputWrite = ps.StandardInput; 

     // uses extra cheap logging facility 
     inputWrite.WriteLine("echo \"Ripping " + copiedFile + " " + 
      temp.ToString() + "\" >> log.txt"); 

     inputWrite.WriteLine("ffmpeg.exe -i \"" + copiedFile + 
      "\" -f image2 -vframes 1 -y -ss 2 tmp\\" + temp.ToString() + 
      ".jpg"); 

     inputWrite.WriteLine("exit"); 

     ps.WaitForExit(3000); 

     if (ps.HasExited) 
     { 
      string thumbFile = Page.MapPath(@"~\Lib\ffmpeg.rev12665\tmp") + 
       @"\" + temp.ToString() + ".jpg"; 
      // ... 
     } 

你的ffmpeg的命令行可能從我的例子急劇變化,但是這是最穩定的方式我發現讓縮略圖出來。我在網上找到的關於ffmpeg的其他內容特別沒有這個解決方案(基於cmd.exe),但這是我工作得很好的唯一一個。祝你好運!

0

當沒有有效的方法來呈現WPF(v3.0)中的視頻時,我寫了VideoRendererElement。它使用一些hackery來使它工作。

如果您想簡化一點,請放棄VRE並使用InteropBitmap進行渲染(WriteableBitmap可以,但效率不高)。還可以放棄SWIG並使C++ dll成爲CLI/C++ dll,這樣您就可以直接與C#中的C++交互(反之亦然)。

另一條路線,你可以去是剛剛創建包含運輸/解碼的東西一個DirectShow源過濾器,你可以使用像我WPF MediaKit要把它呈現到WPF(它使用D3DImage。0黑客)。

另外,不要害怕LGPL。只要你將它保存在它自己的DLL中,並且不要更改源代碼,那麼你就在許可限制之內。

0

您還可以看看可供下載的各種Microsoft Windows Media SDK。在幾年前的一個項目中,我們使用Windows Media Format SDK從上傳的視頻中提取縮略圖。這些SDK也有.NET示例代碼。

4

在我們的項目中,我們使用Microsoft Expression Encoder。它不是免費的。它可以將視頻轉換爲不同的格式和大小,提取縮略圖等

這裏是例子:

using Microsoft.Expression.Encoder; 

//... 
//skiped 
//... 

MediaItem mediaItem = new MediaItem(videoToEncode.SourceFilePath); 
mediaItem.ApplyPreset(PresetFilePath); 

Job job = new Job(); 
job.ApplyPreset(PresetFilePath); // path to preset file, where settings of bit-rate, codec etc 
job.MediaItems.Add(mediaItem); 

job.EncodeProgress += OnProgress; 
job.EncodeCompleted += EncodeCompleted; 

job.DefaultMediaOutputFileName = "{OriginalFilename}.encoded.{DefaultExtension}"; 
job.CreateSubfolder = false; 

job.OutputDirectory = videoToEncode.EncodedFilePath; 
job.Encode(); 
+0

我下載了表達式編碼器的免費版本,並且使用API​​進行了一些演示,並通過反射器中的函數庫查看並嘗試瞭解這些工作是否可行。它確實看起來像一個很好的解決方案,但我仍然不確定我能夠通過自定義協議獲得我需要的控制流。我發現LiveJob對象有一個屬性OutputFormat,看起來它可以通過一種方式來實現自定義流式實現,所以最終可能會工作。 – 2009-12-03 18:49:03

0

我們正在轉換視頻文件轉換爲各種輸出格式(DivX編碼的AVI,FLV,MP4等)爲我們的媒體數據庫應用程序。由於我們一直使用CLI應用程序來進行媒體轉換(談論使用ImageMagick/GS將EPS文件光柵化爲JPG),我們嚴重依賴於FFMPEG-CLI。在我們特殊的環境中,我們使用「啞」UNIX服務器作爲轉換機器(只安裝了sshd,ffmpeg,misc,ffmpeg庫和samba)。它們通過PuTTy的CLI從C#(WCF webservice)通過SSH命令進行控制,以進行真正的轉換。

對ffmpeg的調用通過ssh進行,專用於每個TransformationType。 putty CLI是通過C#的System.Diagnostics.Process命名空間啓動的,輸出和錯誤消息事件是爲了記錄目的而處理的。

互聯網提供了諸如「我怎樣才能使用ffmpeg將mpg轉換爲flv?」這樣的問題的資源,有一點研究可以幫助你。由於我們正在討論版權申請,因此我無法發佈完整的代碼摘錄。但它應該給你一個關於使用C#的可靠,快速的視頻編碼後端架構的想法。

6

DirectShow是你的朋友。 DirectShow是大多數窗口「多媒體」應用程序(如媒體播放器,音頻編碼器等)使用的低級別圖層。

即使這個庫是爲原生開發者製作的,您可以通過DirectShow.net從託管的世界訪問它。 http://directshownet.sourceforge.net這是一個衆所周知的穩定的DirectShow託管包裝。

你唯一需要做的就是學習一點DirectShow來理解graphes和過濾器的概念,然後創建你自己的過濾器和圖形來使用DirectShow的強大功能!