Twisted web.Resourceを使用してMJPEGサーバーを実装しようとしています。 はアップストリームのgstreamerプロセスからデータを取得します TCPにMJPEGデータを書き込むポートlocalhost:9999私は今、この のようなものを持っている:Python-twisted:TCPリーダーとWebリソースの間のバッファリングを防止する
from twisted.internet import reactor, protocol, defer
from twisted.web import server, resource
class MJpegResource(resource.Resource):
def __init__(self, queues):
self.queues = queues
@defer.inlineCallbacks
def deferredRenderer(self, request):
q = defer.DeferredQueue()
self.queues.append([q, request])
while True:
yield q.get()
def render_GET(self, request):
request.setHeader("content-type", 'multipart/x-mixed-replace; boundary=--spionisto')
self.deferredRenderer(request)
return server.NOT_DONE_YET
class JpegStreamReader(protocol.Protocol):
def dataReceived(self, data):
for (q, req) in self.factory.queues:
req.write(data)
q.put('')
root = File('web')
root.putChild('stream.mjpeg', MJpegResource(queues))
factory = protocol.Factory()
factory.protocol = JpegStreamReader
factory.queues = queues
reactor.listenTCP(9999, factory)
site = server.Site(root)
reactor.listenTCP(80, site)
# spawn gstreamer process which writes to port 9999.
# The gstream process is launched using:
# gst-launch-1.0 -v \
# v4l2src device=/dev/video0 \
# ! video/x-raw,framerate=15/1, width=640, height=480 \
# ! jpegenc \
# ! multipartmux boundary=spionisto \
# ! tcpclientsink host=127.0.0.1 port=9999 \
reactor.run()
だから、のようなもの:
gstreamer --> JpegStreamReader --> MJpegResource
これはOK動作しますが、私は時折、 ブラウザ上のビデオは、「これまで何であるか後ろに下がることを発見しましたライブ "(30-40秒程度で )。ブラウザを更新するとすぐに、MJPEGストリームは を「ライブ」に戻します。だから私の疑問は、JpegStreamReaderができないことです。 は、web.http.Requestに対応するTCPソケットに、 として書き込むことができません。gstreamerがTCPソケット9999を埋めていて、JpegStreamReaderへの入力キューにバッファーがついています。
ストリームは「ライブ」となっているので、フレームを廃棄して に戻しても問題ありません。しかし、私は を検出する方法がわからないので、JpegStreamReaderが後ろに落ちていますか? このパイプラインをライブストリームのように振る舞わせる方法についての提案はありますか?
これを行うための基本的なアーキテクチャがある場合は、 の提案も大変ありがとうございます。
ありがとうございました!私はちょうどあなたの提案を実装し、私はそれが実際に私の問題を解決すべきだと思う。私は今、ビデオストリームをしばらく再生していて、内部ネットワークに余分なネットワークアクティビティがある場合、予想されるフレームが落ちるのを見ています。 最後の解決策は、1秒の遅延でresumeProducingに応答することだけです。 後世のために、私は最後に思いついたコードを含めたいと思います。それを自分で別の答えに入れたり、コメントに入れたりするという条約です。別の回答を私がその回答またはこれを受け入れるべきかどうか? –