您好,登錄后才能下訂單哦!
這篇文章主要講解了“Flutter中視頻播放器插件如何使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Flutter中視頻播放器插件如何使用”吧!
在使用視頻播放器插件之前,你應(yīng)該把它添加到你的pubspec.yaml
文件中。當(dāng)你打開pubspec.yaml
文件時,你可以看到運行你的應(yīng)用程序所需的一些配置和依賴性。我們的視頻播放器插件應(yīng)該被添加到dependencies
塊下。
dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 video_player: 2.1.15 //video player
該插件的當(dāng)前版本是2.1.15
,但你可以通過查看插件頁面在這里添加最新版本。如果你保存文件時是在VS Code中,它會自動下載該插件。如果不是,打開終端,寫flutter pub get
來下載該插件。
進入你想添加該插件的文件,并導(dǎo)入video_player.dart
文件。
import 'package:video_player/video_player.dart';
現(xiàn)在你可以在你的項目中使用視頻播放器插件了。
有幾種方法來加載視頻。讓我們從資產(chǎn)中加載我們的例子。在項目的根層創(chuàng)建一個assets/video文件夾,在該文件夾內(nèi)添加一個視頻。然后在pubspec.yaml
,在assets
部分,指定文件路徑,如下所示。
assets: - assets/video/video.mp4
讓我們創(chuàng)建一個單獨的有狀態(tài)的部件,稱為VideoPlayerWidget
,以插入我們的視頻播放器相關(guān)的實現(xiàn)。
你可以在initState
方法中初始化視頻播放器,如下所示。另外,別忘了dispose
,讓視頻播放器做清理工作。
class _VideoPlayerState extends State<VideoPlayerWidget> { late VideoPlayerController _videoPlayerController; @override void initState() { super.initState(); _videoPlayerController = VideoPlayerController.asset( 'assets/video/video.mp4') ..initialize().then((_) { setState(() {}); _videoPlayerController.play(); }); } @override void dispose() { _videoPlayerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Center( child: VideoPlayer(_videoPlayerController), ); } }
VideoPlayerController
必須用late
關(guān)鍵字來指定,因為我們在這一行中仍然沒有定義視頻播放器控制器,我們將在后面做這個。在initState
里面,videoPlayerController
已經(jīng)和資產(chǎn)的路徑一起被初始化。
當(dāng)初始化完成后,它改變了狀態(tài)并重建了小部件。你可以在初始化后開始播放視頻。
取代assets
,你可以使用視頻的URL。為了訪問網(wǎng)絡(luò),你應(yīng)該給Android和iOS添加互聯(lián)網(wǎng)權(quán)限配置。
從根目錄下,進入ios/Runner
,打開info.plist
文件。然后,在該文件中添加以下配置。
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
接下來,去android/app/src/main
,并打開AndroidManifest.xml
。然后,向其添加以下代碼。
<uses-permission android:name="android.permission.INTERNET"/>
現(xiàn)在你可以把asset
改為network
,并在那里添加視頻URL。
@override void initState() { super.initState(); _videoPlayerController = VideoPlayerController.network('video_url_here') ..initialize().then((_) { setState(() {}); _videoPlayerController.play(); }); }
即使初始化已經(jīng)完成,也應(yīng)該有辦法在用戶界面中顯示播放器。VideoPlayer
widget可以用來做到這一點。為了使它工作,你應(yīng)該把控制器作為第一個參數(shù)傳遞給VideoPlayer
widget。
在顯示VideoPlayer
widget之前,最好先檢查初始化是否成功。
@override Widget build(BuildContext context) { return Center( child: _videoPlayerController.value.isInitialized ? VideoPlayer(_videoPlayerController) : Container(), ); }
現(xiàn)在你可以看到屏幕上的視頻了。但是有一個小問題:它的長寬比不合適。這可以通過使用AspectRatio
widget來解決。視頻播放器提供了一個適當(dāng)?shù)囊曨l長寬比,你可以使用這個值來設(shè)置為AspectRatio
widget。
@override Widget build(BuildContext context) { return Center( child: _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController) ) : Container(), ); }
現(xiàn)在你可以看到具有適當(dāng)長寬比的視頻。
首先,讓我們把視頻播放器小部件包在一個列小部件里面,因為我們應(yīng)該把播放和暫停按鈕放在播放器下面。在播放器小組件之后的列內(nèi),讓我們在一個Row
小組件內(nèi)添加兩個ElevatedButton
小組件,在這些按鈕之間讓我們添加一個Padding
小組件以保持一些呼吸空間。
對每個ElevatedButton
,添加相關(guān)的Icons
,作為子部件。然后在播放按鈕onPressed
的回調(diào)里面,你可以參考_videoPlayerController
,并調(diào)用play
方法來開始播放視頻。在暫停按鈕里面,使用pause
方法而不是播放。
現(xiàn)在你可以刪除之前在initState
方法里面添加的播放。
@override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController) ) : Container(), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton(onPressed: (){ _videoPlayerController.pause(); }, child: Icon(Icons.pause)), Padding(padding: EdgeInsets.all(2)), ElevatedButton(onPressed: (){ _videoPlayerController.play(); }, child: Icon(Icons.play_arrow)) ], ) ], ); }
另外,你可以給按鈕添加樣式,得到一個看起來很圓的按鈕,這通常是在視頻播放器中。
@override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _videoPlayerController.value.isInitialized ? AspectRatio( aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController)) : Container(), Padding( padding: EdgeInsets.all(20), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.blue), fixedSize: MaterialStateProperty.all(Size(70, 70)), shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)))), onPressed: () { _videoPlayerController.pause(); }, child: Icon(Icons.pause)), Padding(padding: EdgeInsets.all(2)), ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.redAccent), fixedSize: MaterialStateProperty.all<Size>(Size(80, 80)), shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)))), onPressed: () { _videoPlayerController.play(); }, child: Icon(Icons.play_arrow)) ], ) ], ); }
在實現(xiàn)快進之前,讓我們思考一下我們需要什么。首先,應(yīng)該有一個訪問當(dāng)前視頻位置/時間的方法和一個設(shè)置新值的方法。控制器的seekTo
方法允許我們?yōu)橐曨l設(shè)置持續(xù)時間。
你可以通過視頻播放器value
屬性訪問當(dāng)前的視頻位置,就像下面這樣。
ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.blue), fixedSize: MaterialStateProperty.all(Size(70, 70)), shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)))), onPressed: () { _videoPlayerController.seekTo(Duration( seconds: _videoPlayerController.value.position.inSeconds + 10)); }, child: Icon(Icons.fast_forward))
像這樣,當(dāng)用戶點擊按鈕時,你也可以通過減少10
秒來實現(xiàn)向后倒轉(zhuǎn)。
視頻播放器插件提供了內(nèi)置的功能來添加一個進度條以及一些控件。你可以使用VideoProgressIndicator
widget來實現(xiàn)這個功能。
作為第一個參數(shù),你必須傳遞控制器并設(shè)置allowScrubbing
屬性。allowScrubbing
屬性將允許用戶通過觸摸小組件來滑動進度。通過啟用這個,用戶可以跳到視頻的不同時間戳。此外,你還可以單獨控制尋求欄的背景顏色、緩沖區(qū)顏色和播放區(qū)顏色。
VideoProgressIndicator( _videoPlayerController, allowScrubbing: true, colors: VideoProgressColors( backgroundColor: Colors.red, bufferedColor: Colors.black, playedColor: Colors.blueAccent), )
字幕對你的應(yīng)用程序來說需要兩樣?xùn)|西。第一個是不同時期的段落/單詞列表,第二個是在視頻播放時顯示這些標(biāo)題的方法。為此,應(yīng)該有一種方法來為時間變化添加一個監(jiān)聽器。
視頻播放器包含一個addListener
方法,每秒鐘執(zhí)行一次。你可以使用這個監(jiān)聽器,根據(jù)不同的時間段為視頻播放器提供字幕。
首先,讓我們創(chuàng)建一個Map
,其中包含時間作為一個鍵,字幕文本作為一個值。在Map
,時間的單位將是秒。
Map<int,String> captions = { 5:"First subtitle", 20:"Second subtitle" };
接下來,在初始化視頻播放器時注冊一個Listener
。在回調(diào)里面,你可以檢查視頻是否正在播放,如果視頻正在播放,則獲得當(dāng)前的時間為秒。然后,如果當(dāng)前值包含在captions
地圖中,我們可以像下面這樣將該值設(shè)置為選定的標(biāo)題。
void initState() { super.initState(); _videoPlayerController = VideoPlayerController.asset('assets/video/video.mp4') ..addListener(() { if(_videoPlayerController.value.isPlaying){ setState(() { if(captions.containsKey(_videoPlayerController.value.position.inSeconds)){ selectedCaption = captions[_videoPlayerController.value.position.inSeconds]; } }); } }) ..initialize().then((_) { setState(() {}); _videoPlayerController.play(); }); }
現(xiàn)在你可以使用ClosedCaption
來設(shè)置那個選定的標(biāo)題。你可以給標(biāo)題文本添加一些樣式,以獲得更好的可見性。
ClosedCaption( text: selectedCaption,textStyle: TextStyle(fontSize: 15,color: Colors.white),)
但是,每次標(biāo)題改變時,建立主部件并不是好的做法。因此,我們應(yīng)該把標(biāo)題邏輯提取到一個單獨的小部件。
要注冊一個監(jiān)聽器,你應(yīng)該把視頻控制器傳遞給一個新創(chuàng)建的子部件。
從那里,你可以在子部件內(nèi)注冊監(jiān)聽器。
class VCaption extends StatefulWidget { const VCaption( this.videoPlayerController, ); final VideoPlayerController videoPlayerController; @override _VCaptionState createState() => _VCaptionState(); } class _VCaptionState extends State<VCaption> { String? selectedCaption = ""; Map<int,String> captions = { 5:"First subtitle", 20:"Second subtitle" }; @override void initState() { widget.videoPlayerController.addListener(() { if(widget.videoPlayerController.value.isPlaying){ print("Time ${widget.videoPlayerController.value.position.inSeconds}"); setState(() { if(captions.containsKey(widget.videoPlayerController.value.position.inSeconds)){ selectedCaption = captions[widget.videoPlayerController.value.position.inSeconds]; } }); } }); super.initState(); } @override Widget build(BuildContext context) { return ClosedCaption( text: selectedCaption,textStyle: TextStyle(fontSize: 15,color: Colors.white),); } }
現(xiàn)在我們可以在之前創(chuàng)建的欄目內(nèi)添加這個小部件,并將_videoPlayerController
作為參數(shù)傳遞。你可以在把小部件添加到樹上之前檢查視頻播放器是否已經(jīng)被初始化,就像下面這樣。
_videoPlayerController.value.isInitialized ? VCaption(_videoPlayerController) : Container(),
你可以使用Stack
widget在視頻頂部顯示這些字幕,而不是在視頻下面顯示那些字幕。字幕以及進度指示器已經(jīng)被移到了Stack
widget里面,以便在視頻的頂部顯示。
Stack( children: [ _videoPlayerController.value.isInitialized ? AspectRatio( aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController)) : Container(), Positioned( bottom: 2, width: MediaQuery.of(context).size.width, child: _videoPlayerController.value.isInitialized ? VCaption(_videoPlayerController) : Container(), ), Positioned( bottom: 0, width: MediaQuery.of(context).size.width, child: VideoProgressIndicator( _videoPlayerController, allowScrubbing: false, colors: VideoProgressColors( backgroundColor: Colors.blueGrey, bufferedColor: Colors.blueGrey, playedColor: Colors.blueAccent), )) ], )
感謝各位的閱讀,以上就是“Flutter中視頻播放器插件如何使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Flutter中視頻播放器插件如何使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。