使用flask構(gòu)建直播服務(wù)坎穿。

流是什么?

一種處理實(shí)時(shí)數(shù)據(jù)的方法返劲。還有一種使用場(chǎng)景是當(dāng)前要處理的數(shù)據(jù)很大玲昧,無(wú)法一次放入內(nèi)存,使用流能夠使用很小的內(nèi)存完成處理篮绿。python中主要是靠
生成器來(lái)解決孵延。即在調(diào)用時(shí)才處理。而不是預(yù)先要加載全部數(shù)據(jù)亲配。

def gen():
    yield 1
    yield 2
    yield 3

只有使用next調(diào)用才執(zhí)行尘应。

在flask中的response是支持流的。

實(shí)現(xiàn)視頻流需要的格式是

multipart/x-mixed-replace

這是每一幀需要包含的信息吼虎。

b'--frame\r\n'
        b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n'

程序的基本結(jié)構(gòu)如下犬钢。

index綁定到 / 路由上。返回一個(gè)界面思灰。
gen方法使用生成器產(chǎn)生實(shí)時(shí)數(shù)據(jù)
video_feed 進(jìn)行響應(yīng)
#!/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'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@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玷犹,threaded=True)

這是index.html模板,可以看到src指向上面的viedofeed函數(shù)洒疚,返回流響應(yīng)歹颓。

<html>
  <head>
    <title>Video Streaming Demonstration</title>
  </head>
  <body>
    <h1>flask Video Streaming</h1>
    ![]({{ url_for('video_feed') }})
  </body></html>

下一步就是獲取幀了。首先使用三個(gè)圖片來(lái)替代拳亿。
from time import time

class Camera(object):
    def __init__(self):
        self.frames = [open(f + '.jpg', 'rb').read() for f in ['1', '2', '3']]

    def get_frame(self):
        return self.frames[int(time()) % 3]

這樣實(shí)現(xiàn)的效果是三幅圖片持續(xù)循環(huán)晴股。

下一步是獲取真正的直播流。
使用opencv的python模塊就可以肺魁。

def frames():
    camera = cv2.VideoCapture(0)
    if not camera.isOpened():
        raise RuntimeError('Could not start camera.')

    while True:
        # read current frame
        _, img = camera.read()

        # encode as a jpeg image and return it
        yield cv2.imencode('.jpg', img)[1].tobytes()

一直捕獲數(shù)據(jù)电湘,然后通過(guò)生成器產(chǎn)生。將這個(gè)函數(shù)接入到上面的gen函數(shù)是可以直接執(zhí)行的鹅经。

性能提升

這種不做任何處理的方式會(huì)消耗大量的cpu資源寂呛,其中一個(gè)原因是因?yàn)楹笈_(tái)捕獲的線程和向
客戶端發(fā)送的線程不同步。這就導(dǎo)致后臺(tái)一直在大量獲取數(shù)據(jù)瘾晃,但并不是所有的數(shù)據(jù)都被傳送了出去贷痪。
為了提高性能將兩者進(jìn)行同步。只把后臺(tái)獲取的原始幀進(jìn)行發(fā)送蹦误。
使用線程的threading.event能夠?qū)崿F(xiàn)劫拢。

class CameraEvent(object):
    # ...

class BaseCamera(object):
    # ...
event = CameraEvent()

    # ...

def get_frame(self):
    """Return the current camera frame."""
    BaseCamera.last_access = time.time()

    # 阻塞 等待相機(jī)線程來(lái)喚醒
    BaseCamera.event.wait()
    BaseCamera.event.clear()# 將標(biāo)志位設(shè)置為阻塞

    return BaseCamera.frame

@classmethod
def _thread(cls):
    # ...
    for frame in frames_iterator:
        BaseCamera.frame = frame
        BaseCamera.event.set()  # 喚醒上面阻塞的地方
      #判斷最后查看時(shí)間肉津,來(lái)決定是否關(guān)閉。
      if time.time() - BaseCamera.last_access > 10:
          frames_iterator.close()

上面的wait方法會(huì)阻塞直到標(biāo)志位變?yōu)閠rue舱沧,clear方法將標(biāo)志位重置為false
set方法重置為true 通過(guò)這個(gè)機(jī)制實(shí)現(xiàn)同步妹沙。首先是等待喚醒,然后再將標(biāo)志位
變?yōu)閒lase熟吏,然后繼續(xù)進(jìn)行距糖。

在電腦上開(kāi)啟服務(wù),然后在手機(jī)上查看如下:


直播
直播

原作者
code下載地址
www.yunxcloud.cn

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末牵寺,一起剝皮案震驚了整個(gè)濱河市悍引,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帽氓,老刑警劉巖趣斤,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異杏节,居然都是意外死亡唬渗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)奋渔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)镊逝,“玉大人,你說(shuō)我怎么就攤上這事嫉鲸〕潘猓” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵玄渗,是天一觀的道長(zhǎng)座菠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)藤树,這世上最難降的妖魔是什么浴滴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮岁钓,結(jié)果婚禮上升略,老公的妹妹穿的比我還像新娘。我一直安慰自己屡限,他們只是感情好品嚣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著钧大,像睡著了一般翰撑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上啊央,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天眶诈,我揣著相機(jī)與錄音涨醋,去河邊找鬼。 笑死册养,一個(gè)胖子當(dāng)著我的面吹牛东帅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播球拦,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼帐我!你這毒婦竟也來(lái)了坎炼?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拦键,失蹤者是張志新(化名)和其女友劉穎谣光,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體芬为,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萄金,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了媚朦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氧敢。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖询张,靈堂內(nèi)的尸體忽然破棺而出孙乖,到底是詐尸還是另有隱情,我是刑警寧澤份氧,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布唯袄,位于F島的核電站,受9級(jí)特大地震影響蜗帜,放射性物質(zhì)發(fā)生泄漏恋拷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一厅缺、第九天 我趴在偏房一處隱蔽的房頂上張望蔬顾。 院中可真熱鬧,春花似錦店归、人聲如沸阎抒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)且叁。三九已至,卻和暖如春秩伞,著一層夾襖步出監(jiān)牢的瞬間逞带,已是汗流浹背欺矫。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留展氓,地道東北人穆趴。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像遇汞,于是被迫代替她去往敵國(guó)和親未妹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理空入,服務(wù)發(fā)現(xiàn)络它,斷路器,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在歪赢,面了一些公司化戳,掛了不少,但最終還是拿到小米埋凯、百度点楼、阿里、京東白对、新浪掠廓、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,247評(píng)論 11 349
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,139評(píng)論 25 707
  • 無(wú)奈到標(biāo)題這么俗躏结,然而我并沒(méi)有更好的標(biāo)題寫(xiě)在這里却盘。 每次出差的地點(diǎn)都很偏僻。我總在某個(gè)城市的邊緣的區(qū)下的一個(gè)小鎮(zhèn)里...
    不散園游會(huì)閱讀 180評(píng)論 0 0
  • 今年我們解決三個(gè)大麻煩媳拴,我們就是取得勝利了黄橘。一個(gè)一個(gè)解決,離我寶寶回家的日子就近了屈溉,堅(jiān)持啊塞关,我的小寶貝!我們?nèi)?..
    寒江雪810閱讀 200評(píng)論 0 0