【Flutter】雙路視頻播放方案

最近在做雙路視頻播放,就是在一個頁面播放兩個視頻。我遇到的問題就是音頻焦點沖突問題,在下面說明。

什么是雙路視頻播放(來自AI)

雙路視頻播放(Dual-Video Playback),從字面上理解,就是指在一個屏幕或應用界面上,同時解碼和渲染兩個獨立的視頻流

可以把它想象成有兩列火車在兩條并行的軌道上同時行駛,你可以同時看到兩列火車的狀態。這兩個視頻流可以有多種關系和布局方式。

核心特征

  1. 兩個獨立的視頻源: 這不是將一個視頻畫面分割成兩半,而是實實在在地處理兩個不同的視頻文件或網絡流。例如,一個是?video_A.mp4,另一個是?video_B.mp4

  2. 同時播放: 兩個視頻在時間上是同步或并行播放的。播放/暫停/快進等操作可能聯動控制兩個視頻,也可能允許獨立控制。

  3. 精確同步(關鍵特性): 在很多場景下,雙路視頻播放的難點和核心在于保持兩個視頻畫面的精確時間同步。例如,如果視頻A的第5秒100毫秒對應的是視頻B的第5秒100毫秒,那么在播放時必須保證它們始終對齊,不能出現一個快一個慢的情況。

  4. 靈活的布局: 兩個視頻的畫面可以有多種呈現方式:

    • 畫中畫 (Picture-in-Picture, PiP):一個小視頻窗口懸浮在一個大視頻窗口之上。
    • 左右分屏 (Side-by-Side):屏幕一分為二,左邊播放一個視頻,右邊播放另一個。
    • 上下分屏 (Top-and-Bottom):屏幕一分為二,上邊播放一個視頻,下邊播放另一個。
    • 疊加融合 (Overlay/Blending):一個視頻作為背景,另一個半透明地疊加在上面。

常見的應用場景

雙路視頻播放技術非常有價值,因為它能提供單一視頻無法實現的信息維度和交互體驗。

應用領域具體場景描述示例
在線教育/網絡課程一路視頻播放老師的講課畫面,另一路同步播放課件PPT或屏幕操作的錄像。網易云課堂、Coursera等平臺,老師頭像在角落,主屏幕是課件。
視頻剪輯/后期制作在調色或添加特效時,一路播放原始素材,另一路實時播放處理后的效果,方便進行對比。Adobe Premiere Pro, Final Cut Pro 中的對比視圖功能。
體育賽事直播/分析一路播放賽場的全景視角,另一路播放某個運動員的特寫視角或精彩回放。足球比賽中,同時展示球場全景和某個球星的個人鏡頭。
安防監控在一個屏幕上同時顯示來自不同攝像頭的實時監控畫面。大樓的安保中心,監控墻上顯示著多個區域的實時視頻。
無障礙功能 (Accessibility)一路播放主視頻內容,另一路在角落同步播放手語翻譯的視頻。很多新聞發布會或官方視頻會提供手語翻譯版本。
3D/VR/360°視頻這是一種特殊形式的雙路視頻,系統為左眼和右眼分別渲染一個視頻流,從而創造出立體感和沉浸感。YouTube VR, Oculus TV 等 VR 應用。
互動視頻/游戲允許用戶在不同視角或故事線之間切換,系統在后臺可能需要同時準備好多個視頻流以實現無縫切換。一些互動電影或真人游戲。

技術挑戰

實現穩定流暢的雙路視頻播放并非易事,尤其是在移動端。

  1. 性能消耗巨大: 解碼兩個視頻流(尤其是高清視頻)需要雙倍的CPU/GPU計算資源。這會顯著增加設備的功耗、發熱量,并可能導致卡頓或掉幀。這也是為什么你之前會遇到內存溢出等問題的原因之一,處理雙路視頻對內存管理的要求更高。

  2. 同步難題: 保持兩個視頻流的精確同步是一個巨大的挑戰。網絡延遲的抖動(Jitter)、解碼速度的差異都可能導致音畫或兩個畫面之間出現偏移。需要復雜的時鐘同步機制來校準。

  3. 音軌處理: 兩個視頻通常都有自己的音軌。如何處理音頻?

    • 只播放其中一個視頻的音頻?
    • 將兩個音軌混合(Mix)在一起?
    • 讓用戶自己選擇聽哪一個?
      這都需要在產品設計和技術實現上仔細考慮。
  4. 復雜的播放器控制邏輯: 一個播放器現在需要管理兩個視頻源的狀態,播放/暫停、快進/快退、緩沖狀態、錯誤處理等邏輯都變得復雜了一倍。

總而言之,雙路視頻播放是一項強大的功能,它通過在同一時間呈現更多維度的視覺信息,極大地豐富了應用的功能和用戶體驗,但同時也對應用的性能優化和技術實現提出了更高的要求。

?

初方案

`video_player` 插件

創建兩個獨立的 `VideoPlayerController` 實例,分別控制兩個視頻的播放。

代碼

寫在開頭,重點就是被注釋掉的那句,其實沒必要往下看。

    VideoPlayerController controller1 = VideoPlayerController.networkUrl(Uri.parse(videoUrl),//videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true), //是的,一開始沒加這句!!!這就是問題所在);VideoPlayerController controller2 = VideoPlayerController.networkUrl(Uri.parse(videoUrl),//videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),);

?組件代碼,只是簡單的模擬

@override
Widget build(BuildContext context) {return Scaffold(body: Center(child: Row(children: <Widget>[Expanded(child: _controller1.value.isInitialized? AspectRatio(aspectRatio: _controller1.value.aspectRatio,child: VideoPlayer(_controller1), //這里): Container(),),Expanded(child: _controller2.value.isInitialized? AspectRatio(aspectRatio: _controller2.value.aspectRatio,child: VideoPlayer(_controller2),//這里): Container(),),],),),floatingActionButton: FloatingActionButton(onPressed: () {togglePlayPauseBoth();},child: Icon(_controller1.value.isPlaying ? Icons.pause : Icons.play_arrow,),),);
}void setVolumeBoth(double volume) {controller1?.setVolume(volume);  //注意這里少了一個}void togglePlayPauseBoth() {final bool isPlaying = controller1?.value.isPlaying ?? false;if (isPlaying) {pauseBoth();} else {playBoth();}}void playBoth() {controller1?.play();controller2?.play();}void pauseBoth() {controller1?.pause();controller2?.pause();}void seekBoth(Duration position) {controller1?.seekTo(position);controller2?.seekTo(position);}

問題描述

點擊播放只有第一個視頻播放,而且播放按鈕play_arrow -> pause -> play_arrow。

原因分析

經過了一些不必要的彎路,我終于看到了日志

D/AudioManager(31189): dispatching onAudioFocusChange(-1) ...

?這一行日志就是問題的“確鑿證據”。它告訴我們,系統正在向您的應用發送一個“音頻焦點丟失” (AUDIOFOCUS_LOSS) 的通知。

問題根源:音頻焦點沖突

  1. 什么是音頻焦點??在Android系統中,為了避免多個應用同時播放聲音造成混亂,只有一個應用可以在同一時間“持有”音頻焦點。
  2. 發生了什么??當您調用?playBoth()?時,視頻播放器1(controller1)和視頻播放器2(controller2)?同時向系統請求音頻焦點。
  3. 系統如何反應??Android系統看到來自同一個應用的第二個音頻請求,會認為第一個請求應該被放棄。因此,它會立即給第一個請求者發送一個AUDIOFOCUS_LOSS通知。
  4. video_player插件的默認行為video_player插件在收到“音頻焦點丟失”的通知后,會非常“懂事”地自動暫停播放。

其他方案

1、使用 `multi_video_player` 插件
2、使用 `video_player_mux` 插件

?怎么使用我也只看了官網例子,沒有實踐,有空補上。

一些廢話,記錄bug解決過程

沒有發日志之前AI越走越彎?

問題1:

?一開始這里出現的問題是點擊播放只有第一個視頻播放,而且播放按鈕play_arrow -> pause -> play_arrow。

一開始沒給AI日志信息,所以分析是兩個控制器狀態不統一,給出了解決方案1。

解決方案1:

核心是將播放/暫停的命令統一處理,并建立一個單向的同步機制:始終以后置視頻的狀態為準,強制前置視頻跟隨。

問題2:

由于上訴修改產生了問題2。因為強制兩個視頻狀態同步,主打同生共死,所以兩個視頻他們一起停了,按鈕play_arrow -> pause -> play_arrow。

解決方案2:

撤回解決方法1。

后面還在ai的指導下嘗試了

1、將一個視頻靜音---->沒用。

2、只播放一個視頻永遠只讓一個播放器(主播放器)真正執行play()pause()操作,另一個播放器(從播放器)只通過seekTo()來被動地同步畫面,從而絕不請求音頻焦點。---->卡頓非常明顯,pass。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91685.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91685.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91685.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

筆試——Day25

文章目錄第一題題目思路代碼第二題題目&#xff1a;思路代碼第三題題目&#xff1a;思路代碼第一題 題目 笨小猴 思路 模擬 統計每個字符出現的次數&#xff0c;用最大減最小&#xff0c;判斷是不是質數&#xff1b; 質數的判斷使用試除法&#xff1b; 代碼 第二題 題目&…

【C#學習Day15筆記】拆箱裝箱、 Equals與== 、文件讀取IO

前言在C#第15天的學習中&#xff0c;我深入探索了類型轉換機制、對象比較原理和文件操作技術三大核心主題。這些知識是構建高效、健壯程序的關鍵基礎。本文完整保留我的課堂實踐代碼和命名體系&#xff0c;通過結構化梳理幫助大家掌握這些核心概念。所有代碼示例均來自我的實際…

發電類電力業務許可證申請條件

基本條件&#xff1a;法人資格&#xff1a;申請人必須是依法注冊的企業法人。 財務能力&#xff1a;應具有與所申請從事的電力業務相適應的財務能力。 專業人員要求&#xff1a;生產運行負責人、技術負責人、安全負責人和財務負責人需具備至少3年以上與申請從事的電力業務相關的…

JavaScript 高效入門指南:從基礎到實戰(VSCode 版)

廢話不多說&#xff0c;直接上干貨&#x1f600; 一、先搞定工具&#xff1a;VSCode 配置成「JS 開發神器」 工欲善其事&#xff0c;必先利其器。用 VSCode 寫 JavaScript&#xff0c;這幾個配置能讓你效率翻倍&#xff1a; 1. 必裝插件&#xff08;直接在 VSCode 插件商店搜…

《人形機器人的覺醒:技術革命與碳基未來》——類人關節設計:柔性驅動革命之液壓人工肌肉

目錄&#xff1a;一、人工肌肉的種類及人形機器人適用情況二、人形機器人用人工肌肉科研機構及其最新成果進展三、液壓人工肌肉種類及工作機制四、液壓人工肌肉適用人形機器人的性能要求和局限性五、液壓人工肌肉材料技術進展及其限制與突破六、波士頓動力Spot的液壓靜液傳動系…

26數據結構-順序表

&#x1f4cc;有序順序表的合并 #define MAX_SIZE 20 struct SeqList {int data[MAX_SIZE];int length; }; void mergeArray(SeqList &L1,SeqList &L2,SeqList &L) {int i0,j 0;while(i<L1.length && j<L2.length){if(L1.data[i]<L2.data[j])L.da…

25電賽e題 控制激光開關電路

e題明確說了禁止使用繼電器控制&#xff0c;所以需要自己搭建一個mos管控制電路這里使用mos管來驅動GPIO → 電阻(220Ω) → MOSFET柵極(如IRF520N)MOSFET漏極接激光器正極MOSFET源極接地激光器負極直接接電源連接方式如下這里r36為柵極電阻&#xff0c;需要跟你們使用的mos配合…

ubuntu apt源報錯?

報錯原因&#xff1a;一、網絡連接方面1.網絡不通暢&#xff08;常見&#xff09;簡單來說就是你的虛擬機連不上網&#xff0c;這時候你應該檢查自己的ip 是不是dhcp自動獲取的&#xff0c;或者你的網絡配置是否有誤。2.DNS 解析故障&#xff1a;DNS 服務器配置錯誤或 DNS 服務…

Scene as Occupancy

OccNet https://github.com/OpenDriveLab/OccNet Scene as Occupancy 提出了一種新的場景表示方法&#xff0c; 利用環視攝像頭&#xff0c;采用級聯和時序體素編碼的方式來重建三維Occ場景。Method 1&#xff09;提出的OCCNet首先重建占據描述符&#xff0c;目標是為支持下游任…

Linux基礎復習:字符輸入與輸出

該文僅針對自身對Linux基礎知識不足的地方進行補充擴展&#xff0c;便于鞏固。終端的輸入和輸出由字符設備管理。1、查看當前字符設備# 查看當前bash進程 [rootopenEuler-1 ~]# psPID TTY TIME CMD9662 pts/1 00:00:00 bash9938 pts/1 00:00:00 ps# 該目錄存放了…

【初識數據結構】CS61B中的基數排序

本教程介紹 CS61B 中的基數排序&#xff0c;這是一種可以在某些情況下甚至超越歸并排序、快速排序的特殊的排序方法&#xff0c;但是犧牲了內存空間計數排序 連續編號情形 我們需要對一個編號從 0 到 11 的表進行排序實際上我們可以拿出另一張同樣大小的空白表&#xff0c;在遍…

ReAct模式深度解析:構建具備推理能力的AI智能體架構

本文深入剖析ReAct(Reasoning+Acting)架構設計模式,揭示如何通過推理與行動循環構建具備自主決策能力的AI智能體,并展示其在復雜問題求解中的革命性突破。 引言:從工具調用到自主決策的進化 傳統AI系統面臨的核心瓶頸: #mermaid-svg-orlnKyviyW86xIJZ {font-family:&quo…

Corrosion2靶機攻略

第一步搭建環境 靶機下載地址&#xff1a;https://download.vulnhub.com/corrosion/Corrosion2.ova 下載完成后直接右擊用VM打開&#xff0c;重試一下就可以了 右擊虛擬機設置將網絡連接改成nat模式 第二步信息收集 查看一下靶機的網段&#xff0c;左上角編輯&#xff0c;虛…

SSL 剝離漏洞

一、SSL/TLS 協議基礎?1.1、SSL/TLS 協議的核心功能?SSL/TLS 協議的核心功能主要包括三個方面&#xff1a;加密、認證和完整性校驗&#xff0c;這三大功能共同構建了網絡通信的安全屏障。?&#xff08;一&#xff09;加密?加密是 SSL/TLS 協議最基本的功能。它通過使用對稱…

c++-reverse_iterator

C反向迭代器 反向迭代器是C標準庫提供的一種適配器&#xff0c;它允許我們以相反的順序遍歷容器&#xff0c;反向迭代器是正向迭代器的封裝。 迭代器可以分為兩類&#xff1a;方向性質&#xff1a;單向迭代器&#xff08;Forward Iterator&#xff09;雙向迭代器&#xff08;Bi…

linux內核驅動:電流/電壓/功率監控模塊INA226調試

目錄背景一、芯片介紹二、手冊三、內核驅動配置3.1 設備樹配置3.2 修改內核配置文件3.3 編譯四、內核驅動分析1、初始化流程2、屬性文件/解釋五、調試和計算背景 最近調試了一款德州儀器的帶有I2C控制接口的可以實現電壓、電流、功率監測&#xff0c;并可以進行報警設置的芯片I…

ACL 2024 大模型方向優秀論文:洞察NLP前沿?關鍵突破

關注gongzhonghao【計算機sci論文精選】近年來&#xff0c;以Transformer架構為核心的大語言模型重塑了自然語言處理領域的技術范式。當前ACL相關研究呈現多維度深化態勢&#xff0c;從開源社區推動輕量化架構與低成本訓練技術革新&#xff0c;到學術界探索檢索增強等機制突破長…

樂創E20H1型IO從站與Ethercat轉Profinet網關轉換器的配置應用案例

本案例聚焦于西門子 1200PLC 與 E20H1 - T01 IO 從站的連接。在正常運行過程中&#xff0c;E20H1 - T01 IO 從站需支持 EtherCAT 協議&#xff0c;作為 EtherCAT 從站&#xff1b;而監控系統所采用的西門子 S7 - 1200 系列 PLC 則支持 PROFINET 協議。由于協議的不一致性&#…

【2】專業自定義圖表創建及應用方法

一、專業自定義圖表創建及應用方法1&#xff09;不是圖表的圖表制作方法例題1:迷你圖表制作方法&#xfeff;定義&#xff1a;指依靠Excel基本制圖功能之外的其他功能&#xff08;如公式、條件格式、迷你圖等&#xff09;創建的數據可視化圖表特點&#xff1a;引用數據少且占用…

embodied復現所需docker環境配置粗略流程

由于embodied很多安裝包都需要linux環境&#xff0c;所以為了建立虛擬ubuntu系統&#xff0c;在不適用vmvare的情況&#xff0c;可以考慮使用docker容器來實現&#xff0c;也不會出現的vmware的卡頓情況 1.首先建立容器&#xff0c;并和pycharm建立連接,先安裝docker desktop&a…