日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)Python教程:使用Flask實(shí)現(xiàn)視頻的流媒體傳輸

Flask 是一個(gè) Python 實(shí)現(xiàn)的 Web 開發(fā)微框架。如何用它實(shí)現(xiàn)傳送視頻數(shù)據(jù)流呢?Flask應(yīng)用擁有這樣一種能力,以分割成小數(shù)據(jù)塊的方式,高效地為大型請(qǐng)求提供數(shù)據(jù)。

成都創(chuàng)新互聯(lián)長期為超過千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為義縣企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站,義縣網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

什么是流媒體?

流媒體是一種技術(shù),其中,服務(wù)器以數(shù)據(jù)塊的形式響應(yīng)請(qǐng)求。我能想到一個(gè)原因來解釋為什么這個(gè)技術(shù)可能是有用的:

非常大的響應(yīng) 。對(duì)于非常大的響應(yīng)而言,內(nèi)存中收集的響應(yīng)只返回給客戶端,這是很低效的。另一種方法是將響應(yīng)寫入磁盤,然后使用flask.send_file()返回文件,但是這增加了I/O的組合。假設(shè)數(shù)據(jù)可以分塊生成,以小塊數(shù)據(jù)的方式給請(qǐng)求提供響應(yīng)是一種更好的解決方案。

實(shí)時(shí)數(shù)據(jù) 。對(duì)于一些應(yīng)用,需要請(qǐng)求返回的數(shù)據(jù)來自實(shí)時(shí)數(shù)據(jù)源。

使用Flask實(shí)現(xiàn)流式傳輸

Flask通過使用生成器函數(shù)對(duì)流式響應(yīng)提供本機(jī)支持。生成器是一個(gè)特別的函數(shù),它可以中斷和恢復(fù)。考慮一下下面的函數(shù):

def gen():  
  yield 1 
  yield 2 
  yield 3

這是一個(gè)運(yùn)行三步的函數(shù),其中每步返回一個(gè)值。描述生成器如何實(shí)現(xiàn)超出了本文的范圍,但如果你有點(diǎn)好奇,下面的shell會(huì)話將給你說明生成器是如何被使用的:

>>> x = gen()
>>> x

>>> x.next()
1
>>> x.next()
2
>>> x.next()
3
>>> x.next()
Traceback (most recent call last):
 File "", line 1, in 
StopIteration

在這個(gè)簡單的例子中你能看到,一個(gè)生成器函數(shù)可以順序得返回多個(gè)結(jié)果。Flask使用生成器 函數(shù)這一特性來實(shí)現(xiàn)流式傳輸。

下面的例子說明了如何使用流式傳輸能夠產(chǎn)生大的數(shù)據(jù)表,而不必將整個(gè)表放入內(nèi)存中:

from flask import Response, render_template
from app.models import Stock
  
def generate_stock_table():
  yield render_template('stock_header.html')
  for stock in Stock.query.all():
    yield render_template('stock_row.html', stock=stock)
  yield render_template('stock_footer.html')
  
@app.route('/stock-table')
def stock_table():
  return Response(generate_stock_table())

在這個(gè)例子中,你能看到Flask和生成器函數(shù)是如何一起工作的。返回流式響應(yīng)的路由(route)需要返回一個(gè)由生成器函數(shù)初始化的Response對(duì)象。Flask然后采取調(diào)用生成器,并以分塊的方式吧結(jié)果發(fā)送給客戶端。

對(duì)于這個(gè)特殊的例子,如果你假設(shè)Stock.query.all()返回的數(shù)據(jù)庫查詢結(jié)果是一個(gè)迭代器,那么你能一次生成一個(gè)潛在大表的一行,因此無論查詢中的字符數(shù)量有多少,Python過程中的內(nèi)存消耗不會(huì)因?yàn)檩^大的響應(yīng)字符串而越來越大。

多部分響應(yīng)

上文提到了表的例子以小塊的形式生成一個(gè)傳統(tǒng)網(wǎng)頁,各個(gè)的部分連接成最后的結(jié)果。對(duì)于如何生成較大的響應(yīng)這是一個(gè)很好的例子,但更令人激動(dòng)的事情是處理實(shí)時(shí)數(shù)據(jù)。

使用流式傳輸?shù)囊粋€(gè)有趣的應(yīng)用是使用每個(gè)塊來替換原來頁面中的地方,這能使流在瀏覽器窗口中形成動(dòng)畫。利用這種技術(shù),你可以讓流中每個(gè)數(shù)據(jù)塊成為一個(gè)圖像,這給你提供了一個(gè)運(yùn)行在瀏覽器中的很酷的視頻輸入信號(hào)!

實(shí)現(xiàn)就地更新的秘密是使用多部分響應(yīng)。多部分響應(yīng)由一個(gè)報(bào)頭(header)和很多部分(parts)組成。報(bào)頭包括多部分中的一種內(nèi)容類型,后面的部分由邊界標(biāo)記分隔,每個(gè)部分中含有自身部分中的特定內(nèi)容類型。

對(duì)于不同的需求,這里有一些多部分內(nèi)容類型。對(duì)于具有流式傳輸?shù)?,每個(gè)部分替換先前部分必須使用multipart/x-mixed-replace內(nèi)容類型。為了幫助你了解它到底是什么樣子的,這里有一個(gè)多部分視頻流傳輸?shù)捻憫?yīng)結(jié)構(gòu):

HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace; boundary=frame
  
--frame
Content-Type: image/jpeg
  

--frame
Content-Type: image/jpeg
  

...

正如你上面看到的,這個(gè)結(jié)構(gòu)非常簡單。主要的Content-Type頭被設(shè)為multipart/x-mixed-replace,同時(shí)邊界標(biāo)記也被定義。然后每個(gè)部分中包括,有兩個(gè)短橫線的前綴,及這行上的邊界字符串。每個(gè)部分有自己的Content-Type頭,并且每個(gè)部分可以可選地包括一個(gè)說明所在部分有效載荷的字節(jié)長度的Content-Length頭,但至少對(duì)圖像瀏覽器而言,能夠處理沒有長度的流。

建立一個(gè)實(shí)時(shí)視頻流媒體服務(wù)器

這篇文章中已經(jīng)有足夠的理論,現(xiàn)在是時(shí)候來建立一個(gè)將實(shí)時(shí)視頻流式傳輸?shù)絎eb瀏覽器的完整應(yīng)用。

這里有很多方法將視頻流式傳輸?shù)綖g覽器,并且每個(gè)方法都有其優(yōu)點(diǎn)和缺點(diǎn)。與Flask流特征協(xié)同工作的一個(gè)好方法是流式傳輸獨(dú)立的JPEG圖片序列。這就是動(dòng)態(tài)JPEG。這被用于許多IP監(jiān)控?cái)z像機(jī)。這種方法具有較短的延遲時(shí)間,但傳輸質(zhì)量并不是最好的,因?yàn)閷?duì)于動(dòng)態(tài)影像而言,JPEG壓縮不是非常有效。

下面你可以看到一個(gè)非常簡單但完整的Web應(yīng)用。它可以提供一個(gè)動(dòng)態(tài)JPEG流傳輸:

#!/usr/bin/env python
from flask import Flask, render_template, Response
from camera import Camera
  
app = Flask(__name__)
  
@app.route('/')
def index():  
  return render_template('index.html')
  
def gen(camera):
  while True:
    frame = camera.get_frame()
    yield (b'--framern'
        b'Content-Type: image/jpegrnrn' + frame + b'rn')
  
@app.route('/video_feed')
def video_feed():
  return Response(gen(Camera()),
          mimetype='multipart/x-mixed-replace; boundary=frame')
  
if __name__ == '__main__':
  app.run(host='0.0.0.0', debug=True)

這個(gè)應(yīng)用導(dǎo)入一個(gè)Camera類來負(fù)責(zé)提供幀序列。在這個(gè)例子中,將camera控制部分放入一個(gè)單獨(dú)的模塊是一個(gè)很好的主意。這樣,Web應(yīng)用會(huì)保持干凈、簡單和通用。

該應(yīng)用有兩個(gè)路由(route)。/路由為主頁服務(wù),被定義在index.html模板中。下面你能看到這個(gè)模板文件中的內(nèi)容:

Video Streaming Demonstration
 
 

Video Streaming Demonstration

這是一個(gè)簡單的HTML頁面,只含有一個(gè)標(biāo)題和圖像標(biāo)簽。注意這個(gè)圖像標(biāo)簽的src屬性指向這個(gè)應(yīng)用的第二個(gè)路由,這就是魔法發(fā)生的地方。

/video_feed路由返回流式響應(yīng)。因?yàn)檫@個(gè)流返回要被展示在web頁面上的圖像,在圖像標(biāo)簽的src屬性中,URL指向這個(gè)路由。因?yàn)榇蠖鄶?shù)/所有瀏覽器支持多部分響應(yīng)(如果你找到一個(gè)不支持這個(gè)的瀏覽器,請(qǐng)告訴我),瀏覽器會(huì)通過顯示JPEG圖像流自動(dòng)保持圖像元素的更新。

在/video_feed路由中使用的生成器函數(shù)叫g(shù)en(),將Camera類的一個(gè)實(shí)例作為其參數(shù)。mimetype參數(shù)設(shè)置如上所示,并具有multipart/x-mixed-replace的內(nèi)容類型和設(shè)為"frame"的邊界字符串。

gen()函數(shù)進(jìn)入一個(gè)循環(huán),其中連續(xù)的從camera返回幀作為響應(yīng)塊。如上所示,這個(gè)函數(shù)通過調(diào)用camera.get_frame()方法要求camera提供幀,然后生成幀,使用image/jpeg內(nèi)容類型將該幀格式化為響應(yīng)塊。


本文標(biāo)題:創(chuàng)新互聯(lián)Python教程:使用Flask實(shí)現(xiàn)視頻的流媒體傳輸
網(wǎng)站鏈接:http://www.dlmjj.cn/article/djdpdgj.html