VdoCipher plugin for flutter apps.
This project is a Flutter plugin package, that will enable video playback functionality
by delegating to respective native libraries based on the platform.
Run this command with Flutter:
$ flutter pub add vdocipher_flutter
This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get
):
dependencies:
vdocipher_flutter: ^1.1.0
Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.
Import it
Now in your Dart code, you can use:
import 'package:vdocipher_flutter/vdocipher_flutter.dart';
import 'package:vdocipher_flutter/vdocipher_flutter.dart';
const EmbedInfo SAMPLE_1 = EmbedInfo.streaming(
otp: '20160313versASE313BlEe9YKEaDuju5J0XcX2Z03Hrvm5rzKScvuyojMSBZBxfZ',
playbackInfo: 'eyJ2aWRlb0lkIjoiM2YyOWI1NDM0YTVjNjE1Y2RhMThiMTZhNjIzMmZkNzUifQ==',
embedInfoOptions: EmbedInfoOptions(
autoplay: true
)
);
const EmbedInfo SAMPLE_2 = EmbedInfo.streaming(
otp: '20160313versASE313CBS0f0mkwrNqTswuCYx7Lo41GpQ3r06wbx2WgOUASrQIgH',
playbackInfo: 'eyJ2aWRlb0lkIjoiYTllYWUwOTZjZDg4NGRiYmEzNTE1M2VlNDJhNTA0YTgifQ=='
);
import 'package:flutter/material.dart';
import 'package:vdocipher_flutter/vdocipher_flutter.dart';
import 'package:vdocipher_flutter_example/samples.dart';
class VdoPlaybackView extends StatefulWidget {
@override
_VdoPlaybackViewState createState() => _VdoPlaybackViewState();
}
class _VdoPlaybackViewState extends State<VdoPlaybackView> {
VdoPlayerController? _controller;
final double aspectRatio = 16/9;
ValueNotifier<bool> _isFullScreen = ValueNotifier(false);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Flexible(child: Container(
child: VdoPlayer(
embedInfo: SAMPLE_1,
onPlayerCreated: (controller) => _onPlayerCreated(controller),
onFullscreenChange: _onFullscreenChange,
onError: _onVdoError,
),
width: MediaQuery.of(context).size.width,
height: _isFullScreen.value ? MediaQuery.of(context).size.height : _getHeightForWidth(MediaQuery.of(context).size.width),
)),
ValueListenableBuilder(
valueListenable: _isFullScreen,
builder: (context, dynamic value, child) {
return value ? SizedBox.shrink() : _nonFullScreenContent();
}),
])
);
}
_onVdoError(VdoError vdoError) {
print("Oops, the system encountered a problem: " + vdoError.message);
}
_onPlayerCreated(VdoPlayerController? controller) {
setState(() {
_controller = controller;
_onEventChange(_controller);
});
}
_onEventChange(VdoPlayerController? controller) {
controller!.addListener(() {
VdoPlayerValue value = controller.value;
print("VdoControllerListner"
"\nloading: ${value.isLoading} "
"\nplaying: ${value.isPlaying} "
"\nbuffering: ${value.isBuffering} "
"\nended: ${value.isEnded}"
);
});
}
_onFullscreenChange(isFullscreen) {
setState(() {
_isFullScreen.value = isFullscreen;
});
}
_nonFullScreenContent() {
return Column(
children: [
Text('Sample Playback', style: TextStyle(fontSize: 20.0),)
]);
}
double _getHeightForWidth(double width) {
return width / aspectRatio;
}
}
main.dart #
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:vdocipher_flutter/vdocipher_flutter.dart';
import 'package:vdocipher_flutter_example/vdoplayback_view.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'VdoCipher Sample Application',
home: MyHome(),
navigatorObservers: [VdoPlayerController.navigatorObserver('/player/(.*)')],
theme: ThemeData(
primaryColor: Colors.white,
textTheme: TextTheme(bodyText1: TextStyle(fontSize: 12.0))),
);
}
}
class MyHome extends StatefulWidget {
@override
_MyHomeState createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
String? _nativePlatformLibraryVersion = 'Unknown';
@override
void initState() {
super.initState();
getNativeLibraryVersion();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> getNativeLibraryVersion() async {
String? version;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
version = await (Platform.isIOS ? VdocipherMethodChannel.nativeIOSAndroidLibraryVersion : VdocipherMethodChannel.nativeAndroidLibraryVersion);
} on PlatformException {
version = 'Failed to get native platform library version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_nativePlatformLibraryVersion = version;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('VdoCipher Sample Application'),
),
body: Center(child: Column(
children: <Widget>[
Expanded(child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _goToVideoPlayback,
child: const Text('Online Playback',
style: TextStyle(fontSize: 20)),
),
ElevatedButton(
onPressed: null,
child: const Text('Todo: video selection',
style: TextStyle(fontSize: 20)),
)
])),
Padding(padding: EdgeInsets.all(16.0),
child: Text('Native ${Platform.isIOS ? 'iOS' : 'Android'} library version: $_nativePlatformLibraryVersion',
style: TextStyle(color: Colors.grey, fontSize: 16.0)))
],
))
);
}
void _goToVideoPlayback() {
Navigator.of(context).push(
MaterialPageRoute<void>(
settings: RouteSettings(name: '/player/sample/video'),
builder: (BuildContext context) {
return VdoPlaybackView();
},
),
);
}
}
Property |
Type |
Default / required |
Description |
embedInfo |
EmbedInfo |
required |
Embed info object |
onPlayerCreated(controller) |
Function(VdoController) |
required |
Callback function returns VdoController object |
onFullscreenChange(isFullScreen) |
Function(bool isFullscreen) |
Optional |
Callback function returns true if full screen mode. |
onError(error) |
Function(VdoError) |
Optional |
Callback function returns VdoError object |
aspectRatio |
double |
Default 16:9 |
Aspect ratio |
controls |
bool |
Default true |
Enables player controls, set false to disable player controls |
Property |
Type |
Default / required |
Description |
otp |
String |
required |
a valid OTP |
playbackInfo |
String |
required |
A valid playbackinfo; |
embedInfoOptions |
EmbedInfoOptions |
null |
Embed Info options |
skipDuration |
Duration |
10 seconds |
Forward/Backward skip duration |
playbackSpeedOptions |
List<double> |
[0.75, 1.0, 1.25, 1.5, 1.75, 2.0] |
List of playback speed options between 0.25x to 2.25x |
Property |
Type |
Default / required |
Description |
safetyNetApiKey |
String |
Optional |
A valid SafetyNetApiKey |
preferredCaptionsLanguage |
Optional |
String |
Preferred caption language |
startPosition |
Duration |
Optional |
Video start position |
endPosition |
Duration |
Optional |
Video end position |
resumePosition |
Duration |
Optional |
Vdeo resume position |
maxVideoBitrateKbps |
int |
Optional |
Maximum video bitrate KBPS |
bufferingGoalMs |
int |
Optional |
Buffering goal in MS |
techOverride |
List<String> |
Optional |
Tech override list |
disableAnalytics |
bool |
required (false) |
Disable analytics |
autoplay |
bool |
required (true) |
Start autoplay |
forceLowestBitrate |
bool |
required (false) |
Force lowest bitrate |
forceHighestSupportedBitrate |
bool |
required (false) |
Force highest supported Bitrat |
Property |
Return Type |
Description |
isPlaying |
bool |
Video playing |
isBuffering |
bool |
Video buffering |
isLoading |
bool |
Video loading |
isEnded |
bool |
Video fully watched |
isFullScreen |
ValueNotifier<bool> |
Video is in full screen or portrait mode |
enterFullScreen(bool isFull) |
void |
Set full screen mode |
load(EmbedInfo embedInfo) |
Future<LoadResult> |
Load video with embed info |
play() |
Future<void> |
Play video |
pause() |
Future<void> |
Pause video |
stop() |
Future<void> |
Stop video |
getDuration() |
Future<Duration> |
Get video duration |
getPosition() |
Future<Duration> |
Get current video played position |
seek(Duration target) |
Future<void> |
Seek video to target duration |
setPlaybackSpeed(double speed) |
Future<void> |
Set playback speed |
setCaptionLanguage(String language) |
Future<bool> |
Set Caption Language |
navigatorObserver(String routePathOrRegex) |
void |
SwipeLeft event observer for iOS. Use inside MaterialApp(navigatorObservers: []) |
Property |
Return Type |
Default / required |
Description |
isLoading |
bool |
required |
Properties related to the currently loaded video. |
mediaInfo |
MediaInfo |
required |
Total duration of the video. |
duration |
Duration |
required |
This is [Duration.zero] if the video is not loaded. |
position |
Duration |
required |
The current playback position. |
bufferedPosition |
Duration |
required |
Position up to where the video is buffered. |
skipDuration |
Duration |
required |
Skip Backword/Forward duration |
isPlaying |
bool |
required |
True if the video is playing, false if paused.; |
isBuffering |
bool |
required |
True if the video is buffering.; |
isEnded |
bool |
required |
True if the currently loaded video has played to the end. |
playbackSpeed |
double |
required |
The current playback speed. |
playbackSpeedOptions |
List<double> |
required |
The list of available playback speed options. |
isAdaptive |
bool |
required |
True if track selection is done in adaptive mode, false if a track has been selected explicitly. |
audioTrack |
AudioTrack |
Optional |
Currently selected audio track. |
videoTrack |
VideoTrack |
Optional |
Currently selected video track. |
subtitleTrack |
SubtitleTrack |
Optional |
Currently selected subtitle track. |
audioTracks |
List<AudioTrack> |
Optional |
List of all available audio tracks.; |
videoTracks |
List<VideoTrack> |
Optional |
List of all available video tracks.; |
subtitleTracks |
List<SubtitleTrack> |
Optional |
List of all available subtitle tracks. |
vdoError |
VdoError |
Optional |
If not null, this gives details about an error encountered while loading the video or during playback. |
Property |
Type |
Default / required |
Description |
mediaId |
String |
required |
Media ID in string |
type |
enum MediaInfoType {streaming, offline} |
required |
Media type |
duration |
Duration |
required |
Media duration |
title |
String |
Optional |
Media title |
description |
String |
Optional |
Media description |
Property |
Type |
Default / required |
Description |
id |
int |
required |
A unique identifier for the track in a playback session |
language |
String |
Optional |
Language code for the track; |
bitrate |
int |
Optional |
Bitrate in kbps |
Property |
Type |
Default / required |
Description |
id |
int |
required |
A unique identifier for the track in a playback session |
bitrate |
int |
Optional |
Bitrate in kbps; |
width |
int |
Optional |
Width of the track in px |
height |
int |
Optional |
Height of the track in px |
Property |
Type |
Default / required |
Description |
id |
int |
required |
A unique identifier for the track in a playback session; |
language |
String |
Optional |
Language code for the track; |
Property |
Type |
Default / required |
Description |
code |
int |
required |
Error code |
message |
String |
required |
Error message |
httpStatusCode |
int |
Optional |
HTTP Status Code |