1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

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

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      flutter語音視頻的簡單介紹

      Flutter 音視頻處理FFmpeg

      只能說 Flutter 確實很強大

      成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),湟源企業(yè)網(wǎng)站建設(shè),湟源品牌網(wǎng)站建設(shè),網(wǎng)站定制,湟源網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,湟源網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

      ffmpeg 插件,文檔沒給出如何給視頻添加水印, 但是給出了執(zhí)行命令的方法演示, 這就足夠了。

      添加一個水印:

      String command = "-i " + inputVideoPath +

      " -i "+waterMarkPath+" -filter_complex overlay "+

      outVideoPath+"";

      添加多個水印命令:

      String command = "-i " + inputVideoPath +

      " -i "+waterMarkPath2+" -i "+waterMarkPath+

      " -filter_complex overlay=10:10,overlay=5:5 "+

      outVideoPath+"";

      將視頻轉(zhuǎn)換成小尺寸視頻:

      String command = "-i " + inputVideoPath +" -b:v 10000k -s 216x384 "+ outVideoPath+"";

      如果碰到 App crash with error message: couldn't find "libmobileffmpeg_abidetect.so"

      執(zhí)行

      flutter clean

      flutter doctor -v

      Flutter浪潮下的音視頻研發(fā)探索

      文/陳爐軍

      整理/LiveVideoStack

      大家好,我是阿里巴巴閑魚事業(yè)部的陳爐軍,本次分享的主題是Flutter浪潮下的音視頻研發(fā)探索,主要內(nèi)容是針對閑魚APP在當下流行的跨平臺框架Flutter的大規(guī)模實踐,介紹其在音視頻領(lǐng)域碰到的一些困難以及解決方案。

      分享內(nèi)容主要分為四個方面,首先會對Flutter有一個簡單介紹以及選擇Flutter作為跨平臺框架的原因,其次會介紹Flutter中與音視頻關(guān)系非常大的外接紋理概念,以及對它做出的一些優(yōu)化。之后會對閑魚在音視頻實踐過程中碰到的一些Flutter問題提出了一些解決方案——TPM音視頻框架。最后是閑魚Flutter多媒體開源組件的介紹。

      Flutter

      Flutter是一個跨平臺框架,以往的做法是將音頻、視頻和網(wǎng)絡(luò)這些模塊都下沉到C++層或者ARM層,在其上封裝成一個音視頻的SDK,供UI層的PC、iOS和Android調(diào)用。

      而Flutter做為一個UI層的跨平臺框架,顧名思義就是在UI層也實現(xiàn)了一個跨平臺開發(fā)。可以預(yù)想的是未Flutter發(fā)展的好的話,會逐漸變?yōu)橐粋€從底層到UI層的一個全鏈路的跨平臺開發(fā),技術(shù)人員分別負責SDK和UI層的開發(fā)。

      在Flutter之前已經(jīng)有很多跨平臺UI解決方案,那為什么選擇Flutter呢?

      我們主要考慮性能和跨平臺的能力。

      以往的跨平臺方案比如Weex,ReactNative,Cordova等等因為架構(gòu)的原因無法滿足性能要求,尤其是在音視頻這種性能要求幾乎苛刻的場景。

      而諸如Xamarin等,雖然性能可以和原生App一致,但是大部分邏輯還是需要分平臺實現(xiàn)。

      我們可以看一下,為什么Flutter可以實現(xiàn)高性能:

      原生的native組件渲染以IOS為例,蘋果的UIKit通過調(diào)用平臺自己的繪制框架QuaztCore來實現(xiàn)UI的繪制,圖形繪制也是調(diào)用底層的API,比如OpenGL、Metal等。

      而Flutter也是和原生API邏輯一致,也是通過調(diào)用底層的繪制框架層SKIA實現(xiàn)UI層。這樣相當于Flutter他自己實現(xiàn)了一套UI框架,提供了一種性能超越原生API的跨平臺可能性。

      但是我們說一個框架最終性能怎樣,其實取決于設(shè)計者和開發(fā)者。至于現(xiàn)在到底是一個什么狀況:

      在閑魚的實踐中,我們發(fā)現(xiàn)在正常的開發(fā)沒有特意的去優(yōu)化UI代碼的情況下,在一些低端機上,F(xiàn)lutter界面的流暢性是比Native界面要好的。

      雖然現(xiàn)在閑魚某些場景下會有卡頓閃退等情況,但是這是一個新事物發(fā)展過程中的必然問題,我們相信未來性能肯定不會成為限制Flutter發(fā)展的瓶頸的。

      在閑魚實踐Flutter的過程中,混合棧和音視頻是其中比較難解決的兩個問題,混合棧是指一個APP在Flutter過程中不可能一口氣將所有業(yè)務(wù)全部重寫為Flutter,所以這是一個逐步迭代的過程,這期間原生native界面與Flutter界面共存的狀態(tài)就稱之為混合棧。閑魚在混合棧上也有一些比較好的輸出,例如FlutterBoost。

      外接紋理

      在講音視頻之前需要簡要介紹一下外接紋理的概念,我們將它稱之為是Flutter和Frame之間的橋梁。

      Flutter渲染一幀屏幕數(shù)據(jù)首先要做的是,GPU發(fā)出的VC信號在Flutter的UI線程,通過AOT編譯的機器碼結(jié)合當前Dart Runtime,生成Layer Tree UI樹,Layer Tree上每一個葉子節(jié)點都代表了當前屏幕上所需要渲染的每一個元素,包含了這些元素渲染所需要的內(nèi)容。將Layer Tree拋給GPU線程,在GPU線程內(nèi)調(diào)用Skia去完成整個UI的渲染過程。Layer Tree中有PictureLayer和TextureLayer兩個比較重要的節(jié)點。PictureLayer主要負責屏幕圖片的渲染,F(xiàn)lutter內(nèi)部實現(xiàn)了一套圖片解碼邏輯,在IO線程將圖片讀取或者從網(wǎng)絡(luò)上拉取之后,通過解碼能夠在IO線程上加載出紋理,交給GPU線程將圖片渲染到屏幕上。但是由于音視頻場景下系統(tǒng)API太過繁多,業(yè)務(wù)場景過于復(fù)雜。Flutter沒有一套邏輯去實現(xiàn)跨平臺的音視頻組件,所以說Flutter提出了一種讓第三方開發(fā)者來實現(xiàn)音視頻組件的方式,而這些音視頻組件的視頻渲染出口,就是TextureLayer。

      在整個Layer Tree渲染的過程中,TextureLayer的數(shù)據(jù)紋理需要由外部第三方開發(fā)者來指定,可以把視頻數(shù)據(jù)和播放器數(shù)據(jù)送到TextureLayer里,由Flutter將這些數(shù)據(jù)渲染出來。

      TextureLayer渲染過程:首先判斷Layer是否已經(jīng)初始化,如果沒有就創(chuàng)建一個Texture,然后將Texture Attach到一個SufaceTexture上。

      這個SufaceTexture是音視頻的native代碼可以獲取到的對象,通過這個對象創(chuàng)建的Suface,我們可以將視頻數(shù)據(jù)、攝像頭數(shù)據(jù)解碼放到Suface中,然后Flutter端通過監(jiān)聽SufaceTexture的數(shù)據(jù)更新就可以順利把剛才創(chuàng)建的數(shù)據(jù)更新到它的紋理中,然后再將紋理交給SKIA渲染到屏幕上。

      然而我們?nèi)绻枰肍lutter實現(xiàn)美顏,濾鏡,人臉貼圖等等功能,就需要將視頻數(shù)據(jù)讀取出來,更新到紋理中,再將GPU紋理經(jīng)過美顏濾鏡處理后生成一個處理后的紋理。按Flutter提供的現(xiàn)有能力,必須先將紋理中的數(shù)據(jù)從GPU讀出到CPU中,生成Bitmap后再寫入Surface中,這樣在Flutter中才能順利的更新到視頻數(shù)據(jù),這樣做對系統(tǒng)性能的消耗很大。

      通過對Flutter渲染過程分析,我們知道Flutter底層需要渲染的數(shù)據(jù)就是GPU紋理,而我們經(jīng)過美顏濾鏡處理完成以后的結(jié)果也是GPU紋理,如果可以將它直接交給Flutter渲染,那就可以避免GPU-CPU-GPU這樣的無用循環(huán)。這樣的方法是可行的,但是需要一個條件,就是OpenGL上下文共享。

      OpenGL

      在說上下文之前,得提到一個和上線文息息相關(guān)的概念:線程。

      Flutter引擎啟動后會啟動四個線程:

      第一個線程是UI線程,這是Flutter自己定義的UI線程,主要負責GPU發(fā)出的VSync信號時候用當前Dart編譯的機器碼和當前運行環(huán)境創(chuàng)建出Layer Tree。

      還有就是IO線程和GPU線程。和大部分OpenGL處理解決方案中一樣,F(xiàn)lutter也采取一個線程責資源加載,一部分負責資源渲染這種思路。

      兩個線程之間紋理共享有兩種方式。一種是EGLImage(IOS是 CVOpenGLESTextureCache)。一種是OpenGL Share Context。Flutter通過Share Context來實現(xiàn)紋理共享,將IO線程的Context和GPU線程的Context進行Share,放到同一個Share Group下面,這樣兩個線程下資源是互相可見可以共享的。

      Platform線程是主線程,F(xiàn)lutter中有一個很奇怪的設(shè)定,GPU線程和主線程共用一個Context。并且在主線程也有很多OpenGL 操作。

      這樣的設(shè)計會給音視頻開發(fā)帶來很多問題,后面會詳細說。

      音視頻端美顏處理完成的OpenGL紋理能夠讓Flutter直接使用的條件就是Flutter的上下文需要和平臺音視頻相關(guān)的OpenGL上下文處在一個Share Group下面。

      由于Flutter主線程的Context就是GPU的Context,所以在音視頻端主線程中有一些OpenGL操作的話,很有可能使Flutter整個OpenGL被破壞掉。所以需要將所有的OpenGL操作都限制在子線程中。

      通過上述這兩個條件的處理,我們就可以在沒有增加GPU消耗的前提下實現(xiàn)美顏和濾鏡等等功能。

      TPM

      在經(jīng)過demo驗證之后,我們將這個方案應(yīng)用到閑魚音視頻組件中,但改造過程中發(fā)現(xiàn)了一些問題。

      上圖是攝像頭采集數(shù)據(jù)轉(zhuǎn)換為紋理的一段代碼,其中有兩個操作:首先是切進程,將后面的OpenGL操作都切到cameraQueue中。然后是設(shè)置一次上下文。然后這種限制條件或者說是潛規(guī)則往往在開發(fā)過程中容易被忽略的。而這個條件一旦忽略后果就是出現(xiàn)一些莫名其妙的詭異問題極難排查。因此我們就希望能抽象出一套框架,由框架本身實現(xiàn)線程的切換、上下文和模塊生命周期等的管理,開發(fā)者接入框架以后只需要安心實現(xiàn)自己的算法,而不需要關(guān)心這些潛規(guī)則還有其他一些重復(fù)的邏輯操作。

      在引入Flutter之前閑魚的音視頻架構(gòu)與大部分音視頻邏輯一樣采用分層架構(gòu):

      1:底層是一些獨立模塊

      2:SDK層是對底層模塊的封裝

      3:最上層是UI層。

      引入Flutter之后,通過分析各個模塊的使用場景,我們可以得出一個假設(shè)或者說是抽象:音視頻應(yīng)用在終端上可以歸納為視頻幀解碼之后視頻數(shù)據(jù)幀在各個模塊之間流動的過程,基于這種假設(shè)去做Flutter音視頻框架的抽象。

      咸魚Flutter多媒體開源組件

      整個Flutter音視頻框架抽象分為管線和數(shù)據(jù)的抽象、模塊的抽象、線程統(tǒng)一管理和上下文同一管理四部分。

      管線,其實就是視頻幀流動的管道。數(shù)據(jù),音視頻中涉及到的數(shù)據(jù)包括紋理、Bit Map以及時間戳等。結(jié)合現(xiàn)有的應(yīng)用場景我們定義了管線流通數(shù)據(jù)以Texture為主數(shù)據(jù),同時可以選擇性的添加Bit Map等作為輔助數(shù)據(jù)。這樣的數(shù)據(jù)定義方式,避免重復(fù)的創(chuàng)建和銷毀紋理帶來的性能開銷以及多線程訪問紋理帶來的一些問題。也滿足一些特殊模塊對特殊數(shù)據(jù)的需求。同時也設(shè)計了紋理池來管理管線中的紋理數(shù)據(jù)。

      模塊:如果把管線和數(shù)據(jù)比喻成血管和血液,那框架音視頻的場景就可以比喻成器官,我們根據(jù)模塊所在管線的位置抽象出采集、處理和輸出三個基類。這三個基類里實現(xiàn)了剛才說的線程切換,上下文切換,格式轉(zhuǎn)換等等共同邏輯,各個功能模塊通過集成自這些基類,可以避免很多重復(fù)勞動。

      線程:每一個模塊初始化的時候,初始化函數(shù)就會去線程管理的模塊去獲取自己的線程,線程管理模塊可以決定給初始化函數(shù)分配新的線程或者已經(jīng)分配過其他模塊的線程。

      這樣有三個好處:

      一是可以根據(jù)需要去決定一個線程可以掛載多少模塊,做到線程間的負載均衡。第二,多線程并發(fā)式能夠保證模塊內(nèi)的OpenGL操作是在當前線程內(nèi)而不會跑到主線程去,徹底避免Flutter的OpenGL 環(huán)境被破壞。第三,多線程并行可以充分利用CPU多核架構(gòu),提升處理速度。

      從Flutter端修改Flutter引擎將Context取出后,根據(jù)Context創(chuàng)建上下文的統(tǒng)一管理模塊,每一個模塊在初始化的時候會獲取它的線程,獲取之后會調(diào)用上下文管理模塊獲取自己的上下文。這樣可以保證每一個模塊的上下文都是與Flutter的上下文進行Share的,每個模塊之間資源都是共享可見的,F(xiàn)lutter和音視頻native之間也是互相共享可見的。

      基于上述框架如果要實現(xiàn)一個簡單的場景,比如畫面實時預(yù)覽和濾鏡處理功能,

      1:需要選擇功能模塊,功能模塊包括攝像頭模塊、濾鏡處理模塊和Flutter畫面渲染模塊,

      2:需要配置模塊參數(shù),比如采集分辨率、濾鏡參數(shù)和前后攝像頭設(shè)置等,

      3:在創(chuàng)建視頻管線后使用已配置的參數(shù)創(chuàng)建模塊

      4:最后管線搭載模塊,開啟管線就可以實現(xiàn)這樣簡單的功能。

      上圖為整個功能實現(xiàn)的代碼和結(jié)構(gòu)圖。

      結(jié)合上述音視頻框架,閑魚實現(xiàn)了Flutter多媒體開源組件。

      組要包含四個基本組件分別是:

      1:視頻圖像拍攝組件

      2:播放器組件

      3:視頻圖像編輯組件

      4:相冊選擇組件

      現(xiàn)在這些組件正在走內(nèi)部開源流程。預(yù)計9月份,相冊和播放器會實現(xiàn)開源。

      后續(xù)展望和規(guī)劃

      1:實現(xiàn)開頭所說的從底層SDK到UI的全鏈路的跨端開發(fā)。目前底層框架層和模塊層都是各個平臺各自實現(xiàn),反而是Flutter的UI端進行了跨平臺的統(tǒng)一,所以后續(xù)會將底層也按照音視頻常用做法把邏輯下沉到C++層,盡可能的實現(xiàn)全鏈路跨平臺。

      2:第二部分內(nèi)容為開源共建,閑魚開源的內(nèi)容不僅包括拍攝、編輯組件,還包括了很多底層模塊,希望有開發(fā)者在基于Flutter開發(fā)音視頻應(yīng)用時可以充分利用閑魚開源出的音視頻模塊能力,搭建APP框架,開發(fā)者只要去負責實現(xiàn)特殊需求模塊就可以,盡可能的減少重復(fù)勞動。

      求flutter的教學視頻!!!!

      Flutter教程全套 (全網(wǎng)獨家)百度網(wǎng)盤免費資源在線學習 ?

      鏈接:

      提取碼: m9z8 ?

      Flutter教程全套 (全網(wǎng)獨家)

      第一套:Flutter 攜程17章全-整理好

      第五套:Flutter高仿谷歌翻譯項目課程

      第四套:兩小時掌握Flutter移動App開發(fā)視頻

      第三套:flutter入門到精通全套

      第七套:Flutter小實戰(zhàn)20個

      第六套:仿直聘boss的flutter完整教程

      第九套:Flutter跨平臺開發(fā)

      第二套:flutter移動電商實戰(zhàn)-技術(shù)胖

      第八套:Flutter基礎(chǔ)教程(基礎(chǔ)不好的優(yōu)先看)

      24Flutter的打包.mp4

      23靜態(tài)資源和項目圖片的處理.mp4

      22頁面跳轉(zhuǎn)并返回數(shù)據(jù)_.mp4

      21導(dǎo)航的參數(shù)傳遞和接受-2_.mp4

      20導(dǎo)航的參數(shù)傳遞和接受-1.mp4

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程(28 個視頻)

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #01 環(huán)境搭建 「14:03」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #02 Dart 語言 「17:49」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #03 建立 Android studio 虛擬設(shè)備 「04:12」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #04 建立第一個項目 「08:23」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #05 安裝配置過程中可能遇到的問題(沒遇到者可以跳過) 「05:07」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #06 運行 iOS 模擬器 「04:07」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #07 Flutter 概述 「06:15」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #08 Scaffold AppBar 「Pro」「06:50」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #09 文檔和快捷鍵 「Pro」「02:36」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #10 顏色 Colors 「Pro」「05:47」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #11 自定義字體 fonts 「Pro」「05:09」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #12 hot reload StatelessWidget 「Pro」「04:56」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #13 使用圖片 「Pro」「04:59」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #14 使用圖標 - Icon 「Pro」「01:27」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #15 Button 按鈕使用指南 「Pro」「04:35」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #16 Container 和 Padding 「Pro」「04: 52」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #17 Row 「Pro」「05:24」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #18 Column 「Pro」「05:36」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #19 Flutter Outline Shortcuts 「Pro」「03:18」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #20 Expanded Widgets 「Pro」「06:06」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #21 實戰(zhàn)開始 「Pro」「11:42」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #22 換個編輯器 - Visual Studio Code 「Pro」「04:50」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #23 Stateful vs Stateless Widget 「Pro」「09:45」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #24 列表處理 「Pro」「04:54」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #25 自定義 class 「Pro」「05:37」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #26 card widget 「Pro」「04:26」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #27 Extracting Widgets 「Pro」「06:59」

      Flutter 零基礎(chǔ)入門實戰(zhàn)視頻教程 #28 刪除 - Functions as Parameters - 完結(jié) - 進入實戰(zhàn)課 「Pro」「04:35」

      flutter語言框架如何快速搭建視頻通話場景?

      有兩種方法,一,自己找人才從零開始研發(fā),當然要耗費對應(yīng)的時間和資金,并且需要多次調(diào)試,不能絕對保證能提供良好的體驗感;二,直接接入第三方互聯(lián)網(wǎng)巨頭研發(fā)的視頻通話SDK,要想快速搭建的話,建議選擇后者,即構(gòu)科技的產(chǎn)品就不錯,可以提供90天的體驗。

      Flutter視頻播放器,簡潔!

      注:亮度調(diào)節(jié)和音量調(diào)節(jié)gif無法體現(xiàn),功能是ok的,其次默認Icon鎖的close和open實在難以分辨。

      環(huán)境:Flutter 2.8.1 channel stable ;Dart 2.15.1

      需要音頻播放器的看這里: Flutter音樂播放器

      重點說下這個工具類,因為視頻播放,涉及到狀態(tài)改變有很多,筆者剛開始選擇使用 InheritedWidget 來在眾多的widget之間共享數(shù)據(jù)。但是總感覺這樣有點繁瑣,且不很優(yōu)雅!

      這里非廣告,如果是使用 GetX 就很簡單了,筆者也使用了 GetX 進行封裝了,一瀉千里的趕腳!,但是筆者還是那句話:剛開始接觸Flutter的開發(fā)者不是很建議使用 GetX ,可以先熟悉下Flutter狀態(tài)管理的基礎(chǔ)原理再行使用。而且為了盡量簡潔,還是不引入其他的第三方了。

      我們選擇對第三方插件進行封裝的目的不外乎這幾個:

      于是筆者就寫了一個工具類 VideoPlayerUtils ,專門且只用來處理播放器的所有業(yè)務(wù)。包括暫停、播放、跳轉(zhuǎn)、調(diào)節(jié)音量、調(diào)節(jié)亮度、切換視頻等操作。在所有的widget中不會引用關(guān)于 video_player 或其他第三方插件的任何信息, VideoPlayerUtils 負責widget與播放器之間的所有操作交互。后續(xù)優(yōu)化迭代或更換播放器插件時,只需針對這個工具類進行修改,對所有widget不會有任何的影響,大大的解耦合了。

      其中 VideoPlayerState :

      提供以上的公共屬性,可以通過 VideoPlayerUtils 來獲取對應(yīng)的值,使用 get 只讀,使外界不會誤修改這些屬性,以保證數(shù)值的安全性。開發(fā)者可根據(jù)自身需要自行添加屬性。

      提供以上方法來處理播放器的所有業(yè)務(wù)。同樣的開發(fā)者可根據(jù)自身需要自行添加或修改。

      重點說下這個方法,是整個業(yè)務(wù)的核心方法,控制視頻的播放或暫停。開發(fā)者只要遇到播放或暫停是均可調(diào)用此方法,具體是播放或暫停,內(nèi)部根據(jù)傳入的 url 自行判斷,開發(fā)者不需要關(guān)心。

      切換新視頻也是使用此方法,傳入的 url 與上次不一致,自動切換新視頻。筆者可根據(jù) statusListener 來監(jiān)聽播放狀態(tài)的改變,以此處理自身邏輯。

      這個也需要提下,視頻播放器在播放新視頻時會異步初始化,一般我們的操作是在 initState() 初始化,成功后再 setState() 。這里筆者遇到一個讓人蛋疼的問題:

      我們看 video_player 的使用:

      VideoPlayer(controller) :widget中已經(jīng)持有了controller。本來筆者封裝的目的就是為了讓widget與controller的之間解耦合。但此時的筆者。。。。

      放棄不是不可能放棄的,這輩子都不會放棄的!

      于是筆者取了巧,寫了一個初始化監(jiān)聽器 initializedListener ,包換2個參數(shù): bool,Widget ,初始化是否成功;其中widget為初始化成功返回需要展示的播放器UI,失敗默認返回 const SizedBox() 。

      到這里就可以簡單使用了:

      沒看錯,視頻播放就是這么簡單。

      如果有更多的業(yè)務(wù)功能,筆者也按照自己的需求寫了一套,同樣的開發(fā)者可根據(jù)自身需要自行添加或修改。

      VideoPlayerGestures 主要是處理手勢的,比如快進、快退等跳轉(zhuǎn)播放;左側(cè)上下滑動調(diào)節(jié)亮度;右側(cè)上下滑動調(diào)節(jié)音量;單擊是否開啟沉浸式播放,所有widget的隱藏與顯示;雙擊播放、暫停等。

      哦,還有 PercentageWidget 也放到這個文件下了,就是這玩意:

      因為顯示的百分比與手勢相關(guān),隨著手勢移動而更新。開發(fā)者可自行處理。

      筆者處出于簡單考慮,就按照整個UI的位置命名了。瞅一眼就知道是啥玩意。

      同樣的開發(fā)者可根據(jù)自身需要自行添加或修改。

      就是這玩意:

      同樣的開發(fā)者可根據(jù)自身需要自行添加或修改。話說這個鎖的 Icon 的open和close是真的難分辨!

      就是這玩意:

      同樣的開發(fā)者可根據(jù)自身需要自行添加或修改。

      這玩意是自定義的,別問,問就是跟產(chǎn)品干一架落了下風

      主要就是自定義這玩意:

      同樣的開發(fā)者可根據(jù)自身需要自定義。

      注:這里沒有添加緩沖的進度,開發(fā)可查看 video_player 中的源碼 VideoProgressIndicator ,按業(yè)務(wù)自行定義。

      這玩意就是整合以上的widget,再考慮下全屏的安全區(qū)域,沒啥東西。開發(fā)者可自行處理!

      具體的實現(xiàn)監(jiān)聽器的思路, 看這里 。

      自此一個漂亮的Flutter視頻播放器就已經(jīng)結(jié)束了。如果您覺得對您有些許幫助的話,歡迎 Star !


      當前文章:flutter語音視頻的簡單介紹
      標題URL:http://www.ef60e0e.cn/article/dscocpj.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        嘉鱼县| 醴陵市| 宁陕县| 叶城县| 台南县| 广德县| 南通市| 临海市| 左云县| 黄浦区| 交城县| 肃南| 昔阳县| 金门县| 盐边县| 泗水县| 育儿| 金湖县| 淅川县| 元氏县| 江安县| 清苑县| 临江市| 孝昌县| 德安县| 昭觉县| 正安县| 临沂市| 旬邑县| 集贤县| 安泽县| 微山县| 夹江县| 玉山县| 资源县| 普兰县| 廊坊市| 铜梁县| 黄梅县| 南丰县| 庄河市|