操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    1主界面簡介


    該界面是M2000的主要操作界面,這里是命令航界面,可以看到你要操作對象站點,查詢命令,命令反饋區域及命令參數輸入區域。

    注意:操作對象基站可以多個選取多個基站進行操作,所以執行命令時確認只選中你要操作的對象。

    2查詢

    2.1小區狀態

    2.1.1顯示小區動態信息




    該命令主要是查詢小區的動態參數,可以看出小區是否正常建立;如果無法建立,會顯示“沒有可用的載波資源”等提示。

    2.1.2查詢小區靜態信息




    該命令是顯示小區的靜態參數,就是我們實際配置的小區參數都可以在這里看到,修改PCI的時候重點關注小區的靜態參數。

    1.1.3 解閉塞小區

    UBL CELL:解閉塞小區

    BLK CELL:閉塞小區

    這里在介紹一下華為命令組成及作用:

    動作命令+操作對象

    這里動作命令常用如下表所示:

    UBL

    解閉塞

    BLK

    閉塞

    DSP

    查詢動態信息

    LST

    查詢靜態信息

    ADD

    添加

    RMV

    移除

    MOD

    修改

    這里操作目標很多,包括:EUTRANEXTERNCELL、BRD、SFP等等,常用已經在上面給出部分操作對象。

    2.2eNodeB ID

    LST ENODEBFUNCTION




    這里可以顯示基站的eNodeBID。在修改eNodeBID的時候,必須要執行APP操作來對基站進行復位操作,否者無法成功修改基站ID;同時,修改前必須保證已經刪除站內同頻鄰區。復位操作后,基站可以通過X2接口來更新周圍基站中關于本基站的信息,如外部小區參數,鄰區關系參數等等。

    2.3光功率

    DSP SFP



    這條命令是顯示光模塊的收發功率的,BBU側光模塊位于柜號0,框號0,槽號3,光口號0、2、4;RRU側光模塊位于柜號0,框號60、62、64,槽號0。

    3增加X2鏈路

    步驟1:ADD SCTPLINK



    這里命令是“添加SCTP鏈路”

    這里要注意的是柜號、框號、槽號,這里機柜號一般為0,BBU框號為0,RRU框號根據基帶板在不同的插槽而不同;如果LBBP位于3號槽位,RRU框號起始為60;槽位號,LBBP單板位于0~5號槽位,UMPT單板位于6~7號單板。

    SCTP鏈路是建立基站到基站,基站到核心網的邏輯鏈路。

    建立SCTP鏈路只需要知道源目的IP地址及端口號就可以建立SCTP鏈路,基站與基站的SCTP鏈路是需要雙向配置,到達核心網的不需要。

    步驟2:ADD CPBEARER

    這里用于“添加控制端口承載”

    該命令必須建立在SCTP鏈路之上。

    步驟3::ADD X2INTERFACE

    這里命令是“添加X2接口”

    這里是真正建立X2接口,需要CP承載號,運營商索引值,執行完畢后可以使用DSP X2 INTERFACE查看X2接口的運行狀態。

    4修改功率

    步驟1:MOD PDSCHCFG

    這里的命令是修改小區的RS參考功率,參考信號功率單位是0.1dBm,比如功率是16.4dBm,這里是164。

    5灌包操作

    5.1 linux服務器

    這里的灌包是在Linux服務器上進行的灌包操作,因為Linux服務器特點在于命令行,以下是Linux系統輸入的iperf命令例句:

    iperf -c xxx.xxx.xxx.xxx -u -b 150m -t 99999 -i

    5.2 Windows服務器

    windows上進行灌包比較容易如下圖:

    上面方框是:1.目標IP地址;2.協議類型UDP;3.上行傳輸;4.帶寬大小;5.持續時間;

    然后點擊開始就可以了。

    6下行沖包

    下行沖包是eNodeB側到UE側的沖包,而iperf從服務器上直接灌包到UE側,作用單范圍不同,可以排查相應位置的故障的問題。操作步驟如下:

    步驟1:首先獲取UE的TMSI和E-RAB ID

    有兩種獲取方法可以從信令跟蹤中獲取;也可以在eNodeB上通過DSP ALLUEBASICINFO與DSP UEONLINEINFO兩條命令獲取當前存在的用戶。信令的獲取方法可以參考信令分析指導書。

    在eNodeB上使用命令查詢的方法:適合實驗室或現網小區下只有1個用戶的情況。

    DSP ALLUEBASICINFO:LOCALCELLID=0;

    DSP UEONLINEINFO:DSPMODE=STMSI,MMECODE=22,MTMSI=3255762945;

    其中的ERAB列表如下:

    步驟2:啟動空口下行沖包測試

    在M2000或者webLMT上執行如下MML命令:(注意藍色字體的MMECODE、TMSI和ERAB-ID需要根據實際用戶設置)

    STRUUDATATST:UEIDTYPE=STMSI_TYPE,MMECODE=22,MTMSI=3255762945,ERABID=5,SRCIP="5.5.5.5",SRCPORT=55,DSTIP="6.6.6.6",DSTPORT=55,PKTSIZE=1500,RATE=150000,TIME=360;

    步驟3:查詢結果:DSP UUDATATST:;

    :

    從吞吐量監測中可以看到達到了小區最大峰值(15M、TM1)

    下面是沖50M的測試:




    步驟5:停止空口下行沖包測試


    :


    其他:需要用隨機數來啟動的場景

    UE首次Attach時,沒有TMSI,會以隨機數接入,此時DSP ALLUEBASICINFO查詢到的UE標識為隨機數,后續的命令中都要以隨機數來查詢。如下:

    DSP ALLUEBASICINFO:LOCALCELLID=0;




    DSP UEONLINEINFO:DSPMODE=UEID,UEID="063178DAD2";




    STRUUDATATST:UEIDTYPE=UEID_TYPE,UEID="063178DAD2",ERABID=5,SRCIP="5.5.5.5",SRCPORT=55,DSTIP="6.6.6.6",DSTPORT=55,PKTSIZE=1500,RATE=150000,TIME=360;



    7集中任務管理



    點擊”維護“->”集中任務管理“->”創建”,加上名字,點擊下一步,選擇MML腳本,進行執行。

    8信令跟蹤

    8.1S1接口信令跟蹤



    S1接口是eNodeB到MME/SGW上的鏈路,S1標準信令跟蹤可以跟蹤所有的eNodeB與MME/SGW之間的信令,但無法跟蹤單用戶在S1接口上的信令。X接口自建立是通過S1接口完成自建立的。

    8.2X2接口信令跟蹤

    菜單欄“監控”->“信令跟蹤”->”S1標準跟蹤”,選擇站點,設置時間及周期

    8.3Uu接口信令跟蹤

    菜單欄“監控”->”信令跟蹤管理”-“Uu接口跟蹤“

    8.4RSSI統計監控

    菜單欄”監控“->”信令跟蹤管理“->”RSSI指標”

    8.5用戶數監控

    這里可以看到小區總用戶數、非激活用戶數、保持上行同步用戶數。

    這里可以看到小區RLC層的比特速率,GBR業務速率

    8.6MLB監控

    這里可以看到負載分擔時等效RB運用量,根據具體設置來進行負載分擔,紅框內是參與負載分擔的小區。

    9導出現網數據

    9.1Summary

    這里的Summary表里面記錄了基站無線側所有的參數,基站開站就是導入Summary表開展。

    9.2無線網絡規劃數據



    這里的位置是CME->高級->全景瀏覽,可以根據列出的參數把基站數據導出。

    10算法開關

    10.1eNodeB算法開關

    LST ENODEBALGOSWITCH



    這里基站切換算法開關很多,只需要找到對應的算法開關,用MOD進行修改就可以了。

    10.2小區級算法開關

    LST CELLALGOSWITCH



    11EUTRAN添加鄰區

    11.1同頻

    11.1.1基站內同頻小區建立鄰區關系

    步驟1:ADD EUTRANINTRAFREQNCELL



    該命令為“添加EUTRAN的鄰區關系”

    移動國家碼、移動網絡碼、基站標識、小區標識皆為目標小區的基站參數,本地小區標識為本基站的服務小區標識。

    11.1.2站間同頻小區建立鄰區關系

    步驟1:ADD EUTRANEXTERNALCELL



    該命令的為“添加EUTRAN的外部小區”

    移動網絡碼、移動國家碼、基站標識、小區標識、下行頻點、物理小區標識、跟蹤區域碼都是目標小區的基站參數

    步驟2:ADD EUTRANINTRAFREQNCELL

    該命令為“添加EUTRAN的鄰區關系”

    移動國家碼、移動網絡碼、基站標識、小區標識皆為目標小區的基站參數,本地小區標識為本基站的服務小區標識。這里需要注意,在與周圍建立鄰區關系的時候,保證鄰區的PCI不要相同,否則會產生“PCI沖突告警”。

    這里的“小區偏移量”(即CellIndividualOffset)就是我們所說的CIO參數,系統默認為0dB.

    11.2異頻

    11.2.1站內異頻小區建立鄰區關系

    步驟1:ADD EUTRANINTERNFREQ

    該命令是“添加EUTRAN的異頻相鄰點信息”

    下行頻點及測量帶寬都是目標小區的下行頻點及測量帶寬,這里可以設置異頻切換觸發的類型。

    步驟2:ADD EUTRANINTERFREQNCELL

    11.2.2站外異頻小區建立鄰區關系

    步驟1:ADD EUTRANINTERNFREQ

    該命令為“添加EUTRAN的鄰區關系”

    移動國家碼、移動網絡碼、基站標識、小區標識皆為目標小區的基站參數,本地小區標識為本基站的服務小區標識。

    這里的“小區偏移量”(即CellIndividualOffset)就是我們所說的CIO參數,系統默認為0dB.

    步驟2:ADD EUTRANEXTERNALCELL

    該命令的為“添加EUTRAN的外部小區”

    移動網絡碼、移動國家碼、基站標識、小區標識、下行頻點、物理小區標識、跟蹤區域碼都是目標小區的基站參數

    步驟3:ADD EUTRANINTERFREQNCELL



    該命令為“添加EUTRAN的鄰區關系”

    移動國家碼、移動網絡碼、基站標識、小區標識皆為目標小區的基站參數,本地小區標識為本基站的服務小區標識。

    12KPI指標統計

    步驟1:開啟測量管理



    點擊“性能”->“測量管理”->點擊需要測量的指標->“選擇對象”及“測量指標”及”測量時間“->”確定”。

    步驟2:查詢結果



    點擊”左邊白色區域右鍵點擊新查詢“->”選擇指標、對象“->點擊”線狀圖“及”柱狀圖“來查看結果。


    DeFFcode是一種跨平臺的高性能視頻幀解碼器,通過內部封裝ffmpeg,提供GPU解碼支持,幾行python代碼就能夠快速解碼視頻幀,并具有強大的錯誤處理能力。DeFFcode的APIs支持多種媒體流作為輸入源,例如IP攝像機、常規多媒體文件、屏幕錄制、圖像序列、網絡協議(例如 HTTP(s)、RTP/RSTP)等。由于FFmpeg的學習曲線非常陡峭,封裝FFmpeg后的DeFFcode提供類似OpenCV-Python編碼語法來幫助用戶,使得在Python中學習、創建和開發基于FFmpeg的應用程序變得更加容易。DeFFcode的官方代碼倉庫見:?deffcode???。DeFFcode的官方文檔見??deffcode_doc??。

    DeFFcode的作者專注于音視頻流的處理,除了Deffcode,作者還開源了Python視頻處理庫??VidGear??。VidGear的具體使用見??Python視頻處理庫VidGear使用指北??。DeFFcode還處于快速發展階段,許多功能還需要完善。VidGear提供了比DeFFcode更豐富的視頻處理接口,但是DeFFcode提供了比VidGear更高效更專業的視頻解碼接口。如果想要從事音視頻流解碼相關工作,還是學習ffmpeg的C++代碼使用。

    入門ffmpeg使用或者想要對音視頻處理有所了解推薦看看雷霄驊的博客。雷霄驊是視音頻技術處理的專家,也是國內音視頻領域無償分享技術最多的程序員。但是很不幸雷霄驊因過度勞累于2016年與世長辭,所以大家還是多注意身體健康。身體才是革命的本錢,少加班,該休息就得休息,沒有時間休息的人注定沒有時間生病。

    文章目錄

    • 1 前置知識
    • 1.1 安裝
    • 1.2 DeFFcode功能預覽
    • 2 基礎使用
    • 2.1 解碼視頻文件
    • 2.2 解碼本地攝像頭和屏幕截取
    • 2.3 解碼網絡流
    • 2.4 從圖像序列捕獲幀
    • 2.5 保存視頻
    • 2.6 特定幀存儲
    • 3 進階使用
    • 3.1 虛擬源生成與解碼
    • 3.2 硬件加速視頻解碼
    • 3.3 復雜效果添加
    • 3.4 視頻屬性數據更改
    • 4 參考

    1 前置知識

    1.1 安裝

    對于DeFFcode,python版本需要高于3.7。DeFFcode支持以下系統:

    • 2016以后的linux版本,推薦使用linux系統運行VidGear
    • Windows 7及以上版本
    • MacOS 10.12.6及以上版本

    Deffcode安裝代碼如下:

    pip install -U deffcode

    特別要注意的是DeFFcode必須要安裝ffmpeg執行文件。安裝ffmpeg,其它系統自行搜索安裝方法,ubuntu下直接輸入:

    sudo apt install ffmpeg

    1.2 DeFFcode功能預覽

    視頻流解碼

    DeFFcode核心功能就是利用ffmpeg進行視頻解碼。相關公開測試視頻流地址為:

    • rtsp流:rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4,來源于https://www.wowza.com/developer/rtsp-stream-test
    • http流:http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8,來源于蘋果提供的測試源
    • http流:https://abhitronix.github.io/html/Big_Buck_Bunny_1080_10s_1MB.mp4,來源于DeFFcode
    from deffcode import FFdecoder
    import cv2
    
    # FFedecoder創建視頻源和視頻解碼規則,formulate在ffmpeg中執行語句
    # 本地視頻
    # decoder = FFdecoder("test.mp4").formulate()
    # rtsp流
    decoder = FFdecoder("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4").formulate()
    
    # 從decoder中抓取RGB圖像
    for frame in decoder.generateFrame():
    
        print(frame.shape)
        # 將rgb圖像轉換為bgr圖像,送給opencv展示
        frame_bgr = frame[:, :, ::-1]
        cv2.imshow("Output Frame", frame_bgr)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    # 安全關閉解碼進程
    decoder.terminate()

    視頻流屬性識別

    對于給定的輸入源,DeFFcode使用各種方法識別視頻流其中包含的文件所有屬性,比如是否包含音頻,圖像分辨率,視頻碼率。不同的視頻流返回的屬性參數不同,具體按需要探索下就行了。

    from deffcode import Sourcer
    
    # sourcer設置定位視頻流中的數據信息,probe_stream探測視頻流的輸出
    sourcer = Sourcer("test.mp4").probe_stream()
    
    # 解析為python字典數據
    data = sourcer.retrieve_metadata()
    # pretty_json表示解析為類似json.dump后的json字符串
    print(sourcer.retrieve_metadata(pretty_json=True))

    2 基礎使用

    2.1 解碼視頻文件

    DeFFcode的FFdecoder API很容易支持多媒體視頻文件路徑作為其source參數的輸入。通過它的frame_format參數,您可以輕松解碼所有知名計算機視覺庫(例如 OpenCV)都支持的任何像素格式的視頻幀。FFdecoder API 的generateFrame()函數可用于多種方法來訪問來自給定源的RGB幀,例如生成器(推薦方法)、調用with語句和迭代器。在下面示例中,我們將使用上述訪問方法從給定的視頻文件中解碼默認的RGB24視頻幀。

    生成器調用

    from deffcode import FFdecoder
    
    decoder = FFdecoder("test.mp4").formulate()
    
    # 讀取RGB24圖像
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        print(frame.shape) 
    
    decoder.terminate()

    with調用

    調用with語句方法可用于使代碼更簡單、更清晰、更易讀。這種方法還自動處理FFdecoder API 中的formulate()和terminate()方法的管理,因此不需要顯式調用它們。

    from deffcode import FFdecoder
    import cv2
    
    # 不需要調用formulate和terminate
    with FFdecoder("test.mp4") as decoder:
    
        for frame in decoder.generateFrame():
    
            if frame is None:
                break
    
            print(frame.shape)

    迭代器調用

    迭代器的調用方式類似于OpenCV-Python讀取視頻的方式。

    from deffcode import FFdecoder
    
    decoder = FFdecoder("test.mp4").formulate()
    
    while True:
    
        # next返回迭代器的下一個項目
        frame = next(decoder.generateFrame(), None)
    
        if frame is None:
            break
    
        print(frame.shape) 
    
    decoder.terminate()

    參數設置

    # 設置解碼后的圖像為bgr24,可以直接給opencv使用
    FFdecoder("test.mp4", frame_format="bgr24")
    # 設置解碼后的圖像為灰度圖像,verbose輸出解碼的詳細統計信息
    FFdecoder("test.mp4", frame_format="gray", verbose=True)
    # 設置解碼后的圖像為yuv420p格式,verbose輸出解碼的詳細統計信息
    FFdecoder("test.mp4", frame_format="yuv420p", verbose=True)

    2.2 解碼本地攝像頭和屏幕截取

    這部分不同平臺使用方法不同,而且涉及到很多參數的使用和軟件安裝,所以這里推薦自行閱讀??Decoding Live Feed Devices??。

    2.3 解碼網絡流

    與解碼視頻文件類似,DeFFcode 的 FFdecoder API直接支持具有特定協議(如RTSP/RTP、HTTP(s)、MPEG-TS 等)的網絡流作為其source參數的輸入。以下示例用的都是網絡上的公開視頻流,由于網速問題有可能連接不上。

    http流解碼

    from deffcode import FFdecoder
    import cv2
    
    # 獲得BGR24圖像
    # decoder = FFdecoder("ttp://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8", frame_format="bgr24").formulate()
    decoder = FFdecoder("https://abhitronix.github.io/html/Big_Buck_Bunny_1080_10s_1MB.mp4", frame_format="bgr24").formulate()
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()

    RTSP/RTP流解碼

    from deffcode import FFdecoder
    import cv2
    
    # 設置傳輸協議為tcp
    ffparams = {"-rtsp_transport": "tcp"}
    
    # 取流
    decoder = FFdecoder("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4", frame_format="bgr24", verbose=True, **ffparams).formulate()
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()

    2.4 從圖像序列捕獲幀

    特定命名圖像序列讀取

    下面的代碼展示了如何帶有特定數字標記的圖像序列逐幀讀取圖像。您可以使用以下FFmpeg命令從視頻文件中提取時間長度為2s的圖像序列,注意圖像保存的文件夾路徑應該要預先創建。

    ffmpeg -t 2 -i test.mp4 imgs/image%02d.png

    from deffcode import FFdecoder
    import cv2
    
    # 設置特定數字開始讀圖,在本例為img01.png
    ffparams = {"-ffprefixes":["-start_number", "1"]}
    # 注意圖像數大于三張
    # img%02d.png: 格式化輸出文件名,本示例中輸出img00.png,img01.png, img02.png等
    # 如果是jpeg圖像序列,圖像后綴名應該為jpeg而不是jpg
    decoder = FFdecoder("imgs/img%02d.png", frame_format="bgr24", verbose=True, **ffparams).formulate()
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()

    glob 模式

    如果圖像是連續的,但不一定是數字順序,則通配符(*表示任意數量的任意字符)很有用,但是以下代碼無法在windows下使用。

    from deffcode import FFdecoder
    import cv2
    
    # glob模式抓取圖像
    # glob模式在 Windows FFmpeg 版本上不可用。
    ffparams = {"-ffprefixes":["-pattern_type", "glob"]}
    
    decoder = FFdecoder("imgs/img*.png", frame_format="bgr24", verbose=True, **ffparams).formulate()
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()

    循環讀取圖像

    下面的設置展示了從單個或者多個圖像循環讀取的示例。注意jpg圖像都以jpeg后綴命名。

    #  `-loop 1` 表示循環讀取,loop是bool類型
    ffparams = {"-ffprefixes":["-loop", "1"]}
    
    # 設置單張圖像循環讀取
    decoder = FFdecoder("imgs/img01.png", frame_format="bgr24", verbose=True, **ffparams).formulate()
    
    # 設置多張圖像循環讀取
    decoder = FFdecoder("imgs/img%02d.png", frame_format="bgr24", verbose=True, **ffparams).formulate()

    2.5 保存視頻

    通過OpenCV保存視頻

    from deffcode import FFdecoder
    import json, cv2
    
    decoder = FFdecoder("test.mp4", frame_format="bgr24").formulate()
    
    # decoder.metadata讀取視頻屬性json數據,并轉碼為字典
    metadata_dict = json.loads(decoder.metadata)
    
    FOURCC = cv2.VideoWriter_fourcc("M", "J", "P", "G")
    FRAMERATE = metadata_dict["source_video_framerate"]
    FRAMESIZE = tuple(metadata_dict["source_video_resolution"])
    
    writer = cv2.VideoWriter("output.avi", FOURCC, FRAMERATE, FRAMESIZE)
    
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
        writer.write(frame)
    
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()
    
    writer.release()

    通過VidGear保存視頻(推薦)

    使用這種方式保存視頻,視頻文件壓縮率更高,保存速度更快,但是也CPU利用率也更高。

    from deffcode import FFdecoder
    from vidgear.gears import WriteGear
    import json
    
    decoder = FFdecoder("test.mp4", frame_format="bgr24", verbose=True).formulate()
    
    output_params = {
        "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"]
    }
    
    writer = WriteGear(output_filename="output.mp4", **output_params)
    
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        writer.write(frame)
    
    decoder.terminate()
    
    writer.close()

    參數設置

    以下是各種ffmpeg參數的設置方法,ffparams設置參數后,然后傳入FFdecoder。

    # 截取前3s視頻,按倒序保存
    ffparams = {
        "-vf": "trim=end=7,reverse" 
    }
    
    # 裁剪中央輸入區域,寬高都為輸入視頻的2/3,然后拉伸為原圖像尺寸
    ffparams = {
        "-vf": "crop=2/3*in_w:2/3*in_h"
    }
    
    # 逆時針旋轉圖像30度,用綠色填充旋轉圖像未覆蓋的區域
    ffparams = {
        "-vf": "trim=end=7,rotate=angle=-30*PI/180:fillcolor=green" 
    }
    
    # 保存前7秒視頻,逆時針旋轉90度,保持縱向布局
    # dir為旋轉方向,具體可以搜搜ffmpeg transpose
    ffparams = {
        "-vf": "trim=end=7,transpose=dir=2:passthrough=portrait" 
    }
    
    # 水平翻轉,然后縮放圖像到其原始大小的一半
    ffparams = {
        "-vf": "hflip,scale=w=iw/2:h=ih/2" 
    
    }
    
    # 設置參數
    decoder = FFdecoder(
        "test.mp4", frame_format="bgr24", verbose=True, **ffparams
    ).formulate()

    2.6 特定幀存儲

    DeFFcode的FFdecoder API使用FFmpeg參數-ss提供輕松且精確的幀搜索,使我們能夠從輸入源的特定部分保存圖像。

    from deffcode import FFdecoder
    from PIL import Image
    
    # 定義FFmpeg參數以查找00:00:01.45處圖像,并獲得一幀圖像
    ffparams = {"-ss": "00:00:01.45", "-frames:v": 1}
    
    # 初始化參數
    decoder = FFdecoder("test.mp4", **ffparams).formulate()
    
    # 讀取圖像
    frame = next(decoder.generateFrame(), None)
    
    # 保存圖像
    if not (frame is None):
        im = Image.fromarray(frame)
        im.save("test.png")
    else:
        raise ValueError("Something is wrong!")
    
    decoder.terminate()

    3 進階使用

    3.1 虛擬源生成與解碼

    DeFFcode提供各種創建虛擬視頻流的示例,具體使用見??Decoding Live Virtual Sources??,這里只列出兩個經典的案例。

    從測試源模式生成和解碼幀

    testsrc圖生成一個測試視頻模式,顯示顏色模式、滾動漸變和時間戳。這對于測試目的很有用。

    from deffcode import FFdecoder
    import cv2
    
    # 定義參數
    ffparams = {
        # 播放時間為10秒
        "-ffprefixes": ["-t", "10"],  
    }
    
    # 生成尺寸為1280x720,幀率30的testsrc測試圖像
    decoder = FFdecoder(
        "testsrc=size=1280x720:rate=30",
        source_demuxer="lavfi",
        frame_format="bgr24",
        **ffparams
    ).formulate()
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
        
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()

    使用自定義文本效果從漸變生成和解碼幀

    from deffcode import FFdecoder
    import cv2
    
    ffparams = {
        "-ffprefixes": ["-t", "15"],  # 15秒播放
        "-vf": "drawtext="  # 繪制文本
        + "text='%{localtime\:%X}':"  # 時間 (HH::MM::SS)
        + "fontfile='c\:\/windows\/fonts\/arial.ttf':"  # 字體
        + "x=(w-text_w)/2:y=h-40*t:"  # 向上滾動效果
        + "fontsize=50:"  # 字體大小
        + "fontcolor=white",  # 字體顏色
    }
    
    
    decoder = FFdecoder(
        "gradients=n=3",
        source_demuxer="lavfi",
        frame_format="bgr24",
        **ffparams
    ).formulate()
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()

    3.2 硬件加速視頻解碼

    FFmpeg 提供對不同平臺上不同支持的專用硬件的訪問,以執行一系列與視頻相關的任務,以更快地完成或使用更少的其他資源(特別是 CPU)。使用ffmpeg -decoders終端命令列出所有 FFmpeg 支持的解碼器。可以看看具體ffmpeg支持本機哪種硬件解碼。

    比如判斷ffmpeg是否可以通過依賴于gpu cuda的h264_cuvid解碼,可以輸入以下指令。如果輸出包含了h264_cuvid那么就是支持的,可以通過gpu加速解碼。

    linux系統:ffmpeg -hide_banner -decoders | grep h264

    windows系統:ffmpeg -hide_banner -decoders | findstr h264

    如果支持h264_cuvid加速解碼,可以嘗試以下示例代碼。

    from deffcode import FFdecoder
    import cv2
    
    ffparams = {
        "-vcodec": "h264_cuvid", # CUVID H.264加速視頻解碼
        "-ffprefixes": ["-vsync", "0"], # 視頻同步方法,一般都是自動,這里設置為0
    }
    
    decoder = FFdecoder(
        "test.mp4", frame_format="bgr24", verbose=True, **ffparams
    ).formulate()
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        cv2.imshow("Output", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    decoder.terminate()

    3.3 復雜效果添加

    添加水印

    以下代碼展示了如何在讀取的視頻中添加圖像,并保存視頻到本地。

    from deffcode import FFdecoder
    from vidgear.gears import WriteGear
    import json, cv2
    
    # 定義帶有復雜水印的視頻過濾器
    ffparams = {
        "-ffprefixes": ["-t", "5"],  # 視頻總長度為5秒
        "-clones": [
            "-i",
            "watermark.png",  
        ],
        "-filter_complex": "[1]format=rgba,"  # 設置水印圖像輸入格式
        + "colorchannelmixer=aa=0.7[logo];"  # 設置水印透明度,數值越小越透明
        + "[0][logo]overlay=W-w-{pixel}:H-h-{pixel}:format=auto,".format(  
            pixel=5 # 設置水印圖片在距離輸入視頻右下角5個像素處
        )
        + "format=bgr24",  # 設置輸出格式
    }
    
    
    decoder = FFdecoder(
        "test.mp4", frame_format="bgr24", verbose=True, **ffparams
    ).formulate()
    
    
    output_params = {
        "-input_framerate": json.loads(decoder.metadata)["source_video_framerate"],
    }
    
    # 保存視頻
    writer = WriteGear(output_filename="output.mp4", **output_params)
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        writer.write(frame)
    
    decoder.terminate()
    
    writer.close()

    圖像效果混合

    下面的代碼展示了如何往圖像序列中混合虛擬效果。

    from deffcode import FFdecoder
    from vidgear.gears import WriteGear
    import cv2, json
    
    
    ffparams = {
        "-ffprefixes": [
            "-t", "10", # 視頻長度為10s
            "-f", "lavfi", # 使用輸入虛擬數據
            "-i", "mandelbrot=rate=25", # 視頻幀率
        ],  
        "-custom_resolution": (1280, 720), # 重新設置圖像 1280x720
        "-filter_complex":"[1:v]format=yuv444p[v1];" 
            + "[0:v]format=gbrp10le[v0];"
            + "[v1][v0]scale2ref[v1][v0];"
            + "[v0][v1]blend=all_mode='heat'," 
            + "format=yuv422p10le[v]",
        "-map": "[v]", 
    }
    
    # 設置圖像序列路徑
    decoder = FFdecoder(
        "./imgs/image-%03d.png", frame_format="bgr24", verbose=True, **ffparams
    ).formulate()
    
    output_params = {
        "-input_framerate": 25,  
    }
    
    writer = WriteGear(output_filename="output.mp4", **output_params)
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        writer.write(frame)
    
    decoder.terminate()
    
    writer.close()

    此外Deffcode還支持添加各種藝術效果,具體方法可以閱讀??transcode-art-filtergraphs??

    3.4 視頻屬性數據更改

    添加新屬性

    下面代碼展示了讀取視頻后,往讀取的屬性數據中添加新的屬性,注意該操作并不更改視頻的實際屬性數據。

    from deffcode import FFdecoder
    import json
    
    
    decoder = FFdecoder("test.mp4", verbose=True)
    
    # 設置字典數據
    data = dict(
        mystring="abcd", 
        myint=1234, 
        mylist=[1, "Rohan", ["inner_list"]], 
        mytuple=(1, "John", ("inner_tuple")), 
        mydict={"anotherstring": "hello"}, 
        myjson=json.loads('{"name": "John", "age": 30, "city": "New York"}'),
    )
    
    # 分配視頻的屬性數據
    decoder.metadata = data
    
    decoder.formulate()
    
    print(decoder.metadata)
    
    decoder.terminate()

    修改已有視頻屬性

    在視頻流解碼前,可以設置視頻流的屬性數據,那么就會以更改后的屬性解碼圖像。

    from deffcode import FFdecoder
    import cv2
    
    
    decoder = FFdecoder("test.mp4", verbose=True)
    
    # 替換屬性數據,會以當前屬性解碼視頻
    decoder.metadata = {
        "output_frames_pixfmt": "gray",  # 灰度圖
        "source_video_resolution": [352, 288],  # 寬高更改為352,288
    }
    
    
    decoder.formulate()
    
    
    print(decoder.metadata)
    
    for frame in decoder.generateFrame():
    
        if frame is None:
            break
    
        cv2.imshow("Output gray", frame)
    
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    
    cv2.destroyAllWindows()
    
    decoder.terminate()

    4 參考

    • ??deffcode??
    • ??deffcode_doc??
    • ??VidGear??
    • 雷霄驊
    • ??Decoding Live Feed Devices??
    • ??Decoding Live Virtual Sources??
    • ??transcode-art-filtergraphs??
網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有