2014-06-28 26 views
5

Sadece h264'te video kaydeden özel bir kameraya sahip bir Raspberry Pi kartım var. C# windows form uygulamasında kaydedilen videoyu gerçek zamanlı olarak (1 saniyeden az gecikme ile) oynatmak ve oynatmak için en iyi yöntemi arıyorum. Ek gereksinim, bu tür akışların, örneğin görüntüdeki nesnelerin aranması için, görüntülemeden önce kolaylıkla işlenebilmesidir.C# uygulamasında Raspberry Pi h264 akışını oynatın

Stuff Denedim:

- VLC C# formları app Raspi ve VLC kontrol < sunucu - RTSP ile basit bir çözüm, ancak görüntülenen görüntüde bir ~ 3sec gecikme ciddi bir eksiklik vardır. Ben buffor boyutu/seçenekler vb düzeltmek olamazdı

- C# ham h264 verilerinin alınması ve < mplayer önyüzü geçirmeden, nc ile Raspi üzerinde bir soket oluşturma - Ben sadece raspivid başlatırsanız | nc ve dizüstü bilgisayar nc | mplayer, tam olarak istediğim sonuçları alıyorum, elde ettiğim video çok fazla gerçek zamanlı, ama C# mplayer frontend yaratmaya çalıştığımda ve nc.exe'yi simüle ettiğimde problem ortaya çıkıyor. Belki de h264 verilerini yanlış yazıyorum (sadece onları stdin'e yaz) veya başka bir şey.

- kullanılarak https://github.com/cisco/openh264 < - Her şeyi derlenmiş, ama ben bile C# kullanmaktan bahsetmiyorum, h264dec.exe ile Raspi kaydedilen numune vid.h264 çözmeye alınamıyor.

h264dec.exe vid.h264 

bana hata mesajı verir: iken

h264dec.exe vid.h264 out.yuv 

Bu, 0bytes out.yuv dosyayı üretir "yapılandırma dosyasında belirtilen girdi dosyası yok"

- ffmpeg < - Ben C# app ffplay.exe oynatmayı uygulanan ancak vb Screencaps almak kolay yöntemin olmaması beni daha fazla araştırmak ve geliştirmek cesaretini.

Konuyu doğru bir şekilde yaklaştığımdan bile emin değilim, bu yüzden alabileceğim her tavsiye için gerçekten minnettar olacağım.

DÜZENLEME İşte C# uygulamak çalışıyorum benim 'çalışma' çözüm

raspivid --width 400 --height 300 -t 9999999 --framerate 25 --output - | nc -l 5884 

nc ip_addr 5884 | mplayer -nosound -fps 100 -demuxer +h264es -cache 1024 - 

Burada anahtar sonra mplayer atlama gecikme çünkü, FPS 100'dür ve hemen normale ile aldığı video oynatan hız. Buradaki sorun, video verisini soketten mplayer C# 'ye nasıl geçireceğimi bilmem. Çünkü sanırım stdin (daha önce denedim) ile yapılmıyor. Ben oyuncu buffor içinde ne atlamak ve en kısa sürede bunu aldıkça akışı oynatmak yapmak yoktur 120 seçeneği -fps önce de söylediğim gibi

:

cevap

4

Tamam, aslında ben bu çözmek başardı. PanelId, mplayer'ın yuvalandığı bir panelin bir tanıtıcısıdır.

class Mplayer 
{ 
    Process mplayer; 

    public Mplayer(string path, string pipeName, int panelId) 
    { 
     String args = ""; 
     mplayer = new Process(); 
     mplayer.StartInfo.UseShellExecute = false; 
     mplayer.StartInfo.RedirectStandardInput = true; 
     mplayer.StartInfo.FileName = path; 
     args = @"\\.\pipe\" + pipeName + " -demuxer +h264es -fps 120 -nosound -cache 512"; 
     args += " -nofs -noquiet -identify -slave "; 
     args += " -nomouseinput -sub-fuzziness 1 "; 
     args += " -vo direct3d, -ao dsound -wid "; 
     args += panelId; 
     mplayer.StartInfo.Arguments = args; 
    } 

    public void Start() 
    { 
     mplayer.Start(); 
    } 

    public void End() 
    { 
     mplayer.Kill(); 
    } 
} 

soketinden arka plan işçisi okuma şeyler:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     try 
     { 
      pipeServ.WaitForConnection(); //opcjonalne? 
      StreamWriter sw = new StreamWriter(pipeServ); 
      sw.AutoFlush = true; 

      tcpCamera = new TcpClient(); 
      tcpCamera.Connect(ipAddress, camPort); 
      NetworkStream camStream = tcpCamera.GetStream(); 

      int read = 0; 
      byte[] bytes = new byte[tcpCamera.ReceiveBufferSize]; 
      while (tcpCamera.Connected) 
      { 
       read = camStream.Read(bytes, 0, tcpCamera.ReceiveBufferSize); 
       if (read > 0) 
        pipeServ.Write(bytes, 0, read); 
      } 
     } 
     catch (IOException ex) 
     { 
      //Broken pipe - result of Mplayer exit 
      //MessageBox.Show(ex.Message); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

komut Raspberry Pi üzerinde çalışan. Port numarası, port rasp'ının dinlemenin sayısıdır.

#!/bin/bash 

raspivid --width 1280 --height 720 -t 9999999 --framerate 25 --output - | nc -l PORTNUMBER 
İlgili konular