3GでRaspberry Piビデオを3つの方法でブロードキャストする

趣味として、私はRaspberry Piを選びました。今、私はすでに起こったことを共有することにしました。 要するに、私は3つの方法でビデオ放送を実装しました:HLS for iPhone-20-40秒の遅延、nc(net cat)による遅延-1秒未満の遅延ですが、長時間のバッファリング、およびgstreamerによる:すべては問題ありませんが、クライアントでgstreamerを調べる必要があります。







Piには次の利点があります。



-大規模なコミュニティ( 500万販売、まだクローンがあります);

-安い(半年前に35ドルでB +を購入し、42ドルでBをAV TV経由で接続できます)。

-GPU(VideoCore IV-24Gflops、Intel Edison GPUはブロックされています);

-ピン3.3vの電圧。これは私のようなアマチュアの1.8vよりも優れています。

-ネイティブMIPI CSIカメラOV5647。



私は次のことを行いました-Raspberry Pi、3Gモデム、カメラ、赤外線センサーを接続しました。 赤外線リモコンを使用して、コマンドを実行できます。インターネットのオン/オフ、3つの異なる方法でライブビデオをブロードキャスト、ビデオブロードキャストへのリンクを記載したメールを送信します。 使い方ビデオブロードキャストの舞台裏を残します。



Gasp VideoCore IVのドキュメントが利用可能になった後でも、Raspberry PiはOV5647 5MPカメラ(非常に古くて弱い)での操作方法のみを知っていますが、一部のNokiaの同様のBroadcomチップは42MPカメラで動作します。 代替ボードでは、状況はまったく良くなく、主にUSBカメラが使用されています。



ほとんどのUSBカメラは、jpegで各フレームを圧縮し、このjpegをUSB経由で送信します。 カメラドライバーはjpegを解凍します...したがって、CSIカメラを使用した写真やビデオの品質は、USBを使用した場合よりも著しく向上します。 Piのカメラはキラー機能ですが、誰か(Intel)がGoProレベルでカメラをサポートするボードを実装する場合、もちろん非常に興味深いでしょう。



Piでは、DVK512ボードを装着しました。複数のピ​​ン、4つの氷、4つのボタンがあります。







赤外線センサーと3Gモデムも接続しました。 これをすべてPythonとbashでプログラムしました。 氷を点滅させて3G経由でインターネットにアクセスするには、ルートになる必要があります。



lircパッケージは、赤外線リモコンの操作を担当します。 これにはirrecordチームが含まれており、理論的には任意のリモートコントロールの操作方法を学ぶことができます。または、リモートコントロールの構成をインターネットからダウンロードできます。

apt-get install lirc
      
      







そうすると、ほとんどの3Gモデムが認識されます。

 sudo apt-get install usb-modeswitch
      
      







しかし、USBで適切に動作するために、udevルールを追加しました。 デフォルトでは、何かをUSBに接続すると、デバイス名が予測不能になり、1つの3Gモデムが4つのデバイスttyUSB0、ttyUSB1、ttyUSB2、ttyUSB3にすぐに反映されます。 この問題は、udevルールを記述することで解決でき、システムはデバイスに厳密に定義された名前を付けます。

 /dev/modems/nova_091095493721000_1-1.5
      
      







このような名前は、091095493721000-私のモデムのユニークなシリーズ、1.5-最初で唯一のUSBハブ、5番目のUSBポートを意味します。 (イーサネットは最初のポートに接続されているようです)



os.path.exists( '/ dev / modems / nova_091095493721000_1-1.5')の場合、モデムが挿入されているため、氷を点滅させる必要があります。



ここにudevルール自体があります



 cat /etc/udev/rules.d/52-ftdi.rules SUBSYSTEMS=="usb", KERNEL=="ttyUSB[0-9]*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="sensors/ftdi_%s{serial}_%b" SUBSYSTEMS=="usb", KERNEL=="ttyUSB[0-9]*", ATTRS{idVendor}=="1410", ATTRS{idProduct}=="6000", SYMLINK+="modems/nova_%s{serial}_%b"
      
      







プログラムの本質はサイクルであり、ボタンが押された場合、プロセスを開始または停止し、プロセスが開始された場合、対応する氷が点火されます。



 import lirc import time import subprocess import os import signal import sys import RPi.GPIO as GPIO class Proc(object): def __init__(self, args): self.args = args self.proc = None def start(self): if self.proc != None: if self.proc.poll() == None: return self.proc = subprocess.Popen(self.args, shell=False, preexec_fn=os.setsid) #preexec_fn=os.setsid` def stop(self): if self.proc == None: return #self.proc.kill() try: os.killpg(os.getpgid(self.proc.pid), 15) except OSError as e: print e.strerror try: self.proc.terminate() except OSError as e: print e.strerror self.proc = None def is_live(self): if self.proc != None: if self.proc.poll() == None: return True self.stop() return False GPIO.setmode(GPIO.BCM) GPIO.setup(26, GPIO.OUT) GPIO.setup(12, GPIO.OUT) GPIO.setup(16, GPIO.OUT) GPIO.setup(20, GPIO.OUT) GPIO.output(26,False) GPIO.output(12,False) GPIO.output(16,False) GPIO.output(20,False) ppp = Proc(['./dial.sh']) video = Proc(['./video1.sh']) video2 = Proc(['./video2.sh']) video3 = Proc(['./video3.sh']) ws = Proc(['./webserver.sh']) ws.start() def terminate(): GPIO.cleanup() ppp.stop() video.stop() video2.stop() video3.stop() ws.stop() def signal_term_handler(signal, frame): print 'got SIGTERM' terminate() sys.exit(0) signal.signal(signal.SIGTERM, signal_term_handler) sockid = lirc.init("ctrl1", blocking = False) tac = False try: while True: codeIRs = lirc.nextcode() # print codeIR nocode = True for codeIR in codeIRs: nocode = False print codeIR, len(codeIR) if codeIR == "star": print "STAR DETECTED" if codeIR == "1": ppp.start() if codeIR == "2": ppp.stop() if codeIR == "3": subprocess.call("./notify.py") if codeIR == "4": video.start() if codeIR == "5": video.stop() if codeIR == "7": video2.start() if codeIR == "8": video2.stop() if codeIR == "6": video3.start() if codeIR == "9": video3.stop() tac = not tac GPIO.output(26,ppp.is_live() or (os.path.exists("/dev/modems/nova_091095493721000_1-1.5") and tac)) GPIO.output(12,video.is_live()) GPIO.output(16,video2.is_live() or (video3.is_live() and tac)) GPIO.output(20,ws.is_live()) if nocode: time.sleep(0.1) except KeyboardInterrupt: terminate() print "Good bye"
      
      







Procクラスはプログラムを実行し、サブプロセスとともにプログラムを停止する方法を知っています。 GPIOパケットは氷の点滅に使用され、lircパケットは赤外線センサーの読み取りに使用されます。



まず、プログラムはwebserver.shスクリプトを実行します

 #!/bin/bash cd video python -m SimpleHTTPServer
      
      





このサーバーは、iPhoneでのHLSビデオブロードキャストに必要です。 iPhoneは非常に重要なデバイスであり、ビデオは厳密に定義された特性を受け入れます。



dial.sh-インターネットにアクセスするためのスクリプト

 #!/bin/bash route delete default wvdial
      
      





インターネットが失われた場合、スクリプトは停止し、スクリプトが強制終了された場合、インターネットは失われます。 予想通りに機能します。



iPhoneストリーミング



iPhoneは非常に気難しいデバイスであり、HLSビデオが必要です。 iPhoneプレーヤーは、2秒のビデオファイルをスライス(セグメント化)し、HTTP経由でダウンロードします。 各ファイルには特別なフレームが含まれている必要があります(raspividの-ihスイッチ)。 要するに、ネイティブプログラムPi raspividは一種のセグメントになりますが、どういうわけか間違っています。 Raspbianのavconvとffmpegも、一般に5時間、セグメント化の方法とそのようなことを知っており、gitからダウンロードした新しいffmpegをコンパイルします。 このffmpegは、iPhoneにブロードキャストするためのストリームを正しくカットします。



 #!/bin/bash base="/home/pi/my/py/ir/" cd $base rm -fr video/* raspivid -n -ih -t 0 -ISO 800 -ex night -w 320 -h 240 -fps 30 -b 500000 -o - | \ ./ffmpeg -y \ -loglevel panic \ -i - \ -c:v copy \ -map 0 \ -f ssegment \ -segment_time 1 \ -segment_format mpegts \ -segment_list "$base/video/stream.m3u8" \ -segment_list_size 10 \ -segment_wrap 20 \ -segment_list_flags +live \ -segment_list_type m3u8 \ -segment_list_entry_prefix / \ "$base/video/%03d.ts"
      
      







このブロードキャストは機能しますが、40秒の遅延は正常です。



1秒未満の遅延でブロードキャストする



ここではすべてが簡単です! フローをネット猫に向ける必要があります

 #!/bin/bash raspivid -t 0 -h 240 -w 320 -fps 30 -hf -b 100000 -o - | nc -l 5001
      
      





そして、あなたはmplayerを使用して見ることができます

 nc 94.248.14.212 5001 | mplayer -fps 120 -cache 1024 -
      
      





ただし、翻訳は早めに開始する必要があるため、mplayerは翻訳に追いつく必要があります。 したがって、ブロードキャストよりも-fpsを高く設定する必要があります。 しかし、いずれにせよ、mplayerが追いつくと、けいれんします。



gstreamerによるストリーミングが最も最適であることが判明しました



 $> cat video3.sh #!/bin/bash raspivid -t 0 -h 240 -w 320 -fps 25 -hf -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=0.0.0.0 port=5000
      
      







それに応じて見ます



 gst-launch-1.0 -v tcpclientsrc host=94.248.14.212 port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false
      
      







Google Playには、gstreamerのビデオを表示できるアプリケーションがあります。



PS:コンポーネントの価格。だから誰も払いすぎないように。 (送料無料を含む)

6個の中国製18650バッテリー-11ドル

1個のパナソニックNRC18650b-10ドル(ほぼテスラのように)

1つの18650 $ 1.24のUSBバンク

DVK 512-15ドル

IRセンサー+リモート-2.17ドル

今では、Raspberry Pi 2を購入する価値があります〜40ドル



PS2:Piでは、すべてのピンに2つの名前があります。 ネイティブBroadcom GPIO.setmode(GPIO.BCM)およびすべてのRaspberry Pi GPIO.setmode(GPIO.BOARD)に共通ですが、DVK512には独自の3番目の番号があります。







Led0-26#GPIO.setmode(GPIO.BCM)、別名GPIO.setmode(GPIO.BOARD)-37、別名DV512 P25

Led1-12

Led2-16

Led3-20

Key0-5

Key1-6

Key2-13

Key3-19



ハッピーハッキング



All Articles