flutter video_player
Flutterで動画を再生する
Flutterで動画を再生するにはvideo_playerというパッケージを昔から使うことが多い。メンテナンスも継続されているので信用できる。
公式の解説
A Flutter plugin for iOS, Android and Web for playing back video on a Widget surface.
iOS、Android、Web用のFlutterプラグインで、Widgetサーフェス上でビデオを再生します。
add package:
flutter pub add video_player
iOS, Androidに設定が必要なので追加する。問題なく動いてはいたが。。。
Setup
iOS
If you need to access videos using http (rather than https) URLs, you will need to add the appropriate NSAppTransportSecurity permissions to your app's Info.plist file, located in <project root>/ios/Runner/Info.plist. See Apple's documentation to determine the right combination of entries for your use case and supported iOS versions.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Android
If you are using network-based videos, ensure that the following permission is present in your Android Manifest file, located in <project root>/android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
example
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(const VideoApp());
/// Stateful widget to fetch and then display video content.
class VideoApp extends StatefulWidget {
const VideoApp({super.key});
_VideoAppState createState() => _VideoAppState();
}
class _VideoAppState extends State<VideoApp> {
late VideoPlayerController _controller;
void initState() {
super.initState();
_controller = VideoPlayerController.networkUrl(Uri.parse(
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'))
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {});
});
}
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Demo',
home: Scaffold(
body: Center(
child: _controller.value.isInitialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
),
);
}
void dispose() {
_controller.dispose();
super.dispose();
}
}
.then以外の書き方もある
async/await
で非同期処理を書くことのほうが多いと思う。リファクタリングして書き直してみた。参考までどうぞ💁
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(const VideoApp());
class VideoApp extends StatelessWidget {
const VideoApp({super.key});
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Video Demo',
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
const VideoPlayerScreen({super.key});
VideoPlayerScreenState createState() => VideoPlayerScreenState();
}
class VideoPlayerScreenState extends State<VideoPlayerScreen> {
late VideoPlayerController _controller;
bool _isInitialized = false;
void initState() {
super.initState();
_initializeVideoPlayer();
}
Future<void> _initializeVideoPlayer() async {
_controller = VideoPlayerController.networkUrl(
Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'),
);
try {
await _controller.initialize();
setState(() {
_isInitialized = true;
});
} catch (error) {
print('Error initializing video player: $error');
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('async/await'),
),
body: Center(
child: _isInitialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: const CircularProgressIndicator(),
),
floatingActionButton: FloatingActionButton(
onPressed: _togglePlayPause,
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
);
}
void _togglePlayPause() {
setState(() {
_controller.value.isPlaying ? _controller.pause() : _controller.play();
});
}
void dispose() {
_controller.dispose();
super.dispose();
}
}
最後に
動画再生機能を使った副業をやったときに使ったことがあるのですが当時使ったときは技術記事に書いてあるソースコードが古くて参考にならなかった💦
そのときは、thenで処理を書いてましたね。
Firebase Storageに保存した動画のパスを指定して表示する機能を当時は実装していましたね。
Discussion