Simple 360 video player plugin (Android, iOS support)
Flutter Version <= 2.10.5 used this plugin version 0.0.6
Flutter Version >= 3.0.0 used this plugin version 0.0.8
The Android uses the open source AndroidX Media3
AndroidX Media3 : 1.1.1 (via Google ExoPlayer Version: 2.19.1)
The iOS uses the open source Swifty360Player
Swifty360Player Version: 0.2.5
Add pubspec.yaml dependencies.
dependencies:
video_360: ^0.0.9
Android Requirements
Minimum SDK Target : 19
iOS Requirements
Minimum iOS Target : 11.0
Swift Version : 5.x
importing the libray:
import 'package:video_360/video_360.dart';
Add Video360View:
Video360View(
onVideo360ViewCreated: _onVideo360ViewCreated,
url: YOUR_360_VIDEO_URL,
isRepeat: true, // defalut : false
onPlayInfo: (Video360PlayInfo info) {
// Play info Callback
},
)
Video360Controller Method
play() : video play
stop() : video stop
reset() : video reset
jumpTo() : video jump, parameter is millisecond
seekTo() : video seek, parameter is plus, minus millisecond
sample code:
import 'package:flutter/material.dart';
import 'package:video_360/video_360.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Video360Controller? controller;
String durationText = '';
String totalText = '';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
var statusBar = MediaQuery.of(context).padding.top;
var width = MediaQuery.of(context).size.width;
var height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
title: const Text('Video 360 Plugin example app'),
),
body: Stack(
children: [
Center(
child: Container(
width: width,
height: height,
child: Video360View(
onVideo360ViewCreated: _onVideo360ViewCreated,
url: 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/m3u8s/105560.m3u8',
onPlayInfo: (Video360PlayInfo info) {
setState(() {
durationText = info.duration.toString();
totalText = info.total.toString();
});
},
),
),
),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
MaterialButton(
onPressed: () {
controller?.play();
},
color: Colors.grey[100],
child: Text('Play'),
),
MaterialButton(
onPressed: () {
controller?.stop();
},
color: Colors.grey[100],
child: Text('Stop'),
),
MaterialButton(
onPressed: () {
controller?.reset();
},
color: Colors.grey[100],
child: Text('Reset'),
),
MaterialButton(
onPressed: () {
controller?.jumpTo(80000);
},
color: Colors.grey[100],
child: Text('1:20'),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
MaterialButton(
onPressed: () {
controller?.seekTo(-2000);
},
color: Colors.grey[100],
child: Text('<<'),
),
MaterialButton(
onPressed: () {
controller?.seekTo(2000);
},
color: Colors.grey[100],
child: Text('>>'),
),
Flexible(
child: MaterialButton(
onPressed: () {
},
color: Colors.grey[100],
child: Text(durationText + ' / ' + totalText),
),
),
],
)
],
)
],
),
);
}
_onVideo360ViewCreated(Video360Controller? controller) {
this.controller = controller;
this.controller.play();
}
}