Skip to content

Commit f376a5f

Browse files
[video_player_avplay] Add _suspend and _restore for handing onPause and onResume lifecycle event (#825)
Co-authored-by: yying.jin <yying.jin@samsung.com>
1 parent fc822ad commit f376a5f

20 files changed

+1111
-112
lines changed

packages/video_player_avplay/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.5.20
2+
3+
* Add suspend and restore interface.
4+
15
## 0.5.19
26

37
* Upgrade native player

packages/video_player_avplay/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ To use this package, add `video_player_avplay` as a dependency in your `pubspec.
1212

1313
```yaml
1414
dependencies:
15-
video_player_avplay: ^0.5.19
15+
video_player_avplay: ^0.5.20
1616
```
1717
1818
Then you can import `video_player_avplay` in your Dart code:

packages/video_player_avplay/example/lib/main.dart

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class _App extends StatelessWidget {
2222
@override
2323
Widget build(BuildContext context) {
2424
return DefaultTabController(
25-
length: 7,
25+
length: 9,
2626
child: Scaffold(
2727
key: const ValueKey<String>('home_page'),
2828
appBar: AppBar(
@@ -37,6 +37,8 @@ class _App extends StatelessWidget {
3737
Tab(icon: Icon(Icons.cloud), text: 'DRM PlayReady'),
3838
Tab(icon: Icon(Icons.cloud), text: 'Track'),
3939
Tab(icon: Icon(Icons.cloud), text: 'Asset'),
40+
Tab(icon: Icon(Icons.live_tv), text: 'Live'),
41+
Tab(icon: Icon(Icons.local_florist), text: 'ChangeURLTest'),
4042
],
4143
),
4244
),
@@ -49,6 +51,8 @@ class _App extends StatelessWidget {
4951
_DrmRemoteVideo2(),
5052
_TrackTest(),
5153
_AssetVideo(),
54+
_LiveRemoteVideo(),
55+
_TestRemoteVideo(),
5256
],
5357
),
5458
),
@@ -748,3 +752,142 @@ class _GetTextTrackButton extends StatelessWidget {
748752
);
749753
}
750754
}
755+
756+
class _LiveRemoteVideo extends StatefulWidget {
757+
@override
758+
State<_LiveRemoteVideo> createState() => _LiveRomoteVideoState();
759+
}
760+
761+
class _LiveRomoteVideoState extends State<_LiveRemoteVideo> {
762+
late VideoPlayerController _controller;
763+
764+
@override
765+
void initState() {
766+
super.initState();
767+
_controller = VideoPlayerController.network(
768+
'https://hlive.ktv.go.kr/live/klive_h.stream/playlist.m3u8',
769+
);
770+
771+
_controller.addListener(() {
772+
if (_controller.value.hasError) {
773+
print(_controller.value.errorDescription);
774+
}
775+
setState(() {});
776+
});
777+
_controller.setLooping(true);
778+
_controller.initialize().then((_) => setState(() {}));
779+
_controller.play();
780+
}
781+
782+
@override
783+
void dispose() {
784+
_controller.dispose();
785+
super.dispose();
786+
}
787+
788+
@override
789+
Widget build(BuildContext context) {
790+
return SingleChildScrollView(
791+
child: Column(
792+
children: <Widget>[
793+
Container(padding: const EdgeInsets.only(top: 20.0)),
794+
const Text('Playing Live TV'),
795+
Container(
796+
padding: const EdgeInsets.all(20),
797+
child: AspectRatio(
798+
aspectRatio: _controller.value.aspectRatio,
799+
child: Stack(
800+
alignment: Alignment.bottomCenter,
801+
children: <Widget>[
802+
VideoPlayer(_controller),
803+
ClosedCaption(text: _controller.value.caption.text),
804+
_ControlsOverlay(controller: _controller),
805+
VideoProgressIndicator(_controller, allowScrubbing: true),
806+
],
807+
),
808+
),
809+
),
810+
],
811+
),
812+
);
813+
}
814+
}
815+
816+
class _TestRemoteVideo extends StatefulWidget {
817+
@override
818+
State<_TestRemoteVideo> createState() => _TestRemoteVideoState();
819+
}
820+
821+
class _TestRemoteVideoState extends State<_TestRemoteVideo> {
822+
late VideoPlayerController _controller;
823+
824+
@override
825+
void initState() {
826+
super.initState();
827+
_controller = VideoPlayerController.network(
828+
'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8',
829+
);
830+
831+
_controller.addListener(() {
832+
if (_controller.value.hasError) {
833+
print(_controller.value.errorDescription);
834+
}
835+
setState(() {});
836+
});
837+
_controller.setLooping(true);
838+
_controller.initialize().then((_) => setState(() {}));
839+
_controller.play();
840+
_controller.setRestoreData(
841+
restoreDataSource: restoreDataSource,
842+
resumeTime: restoreTime,
843+
);
844+
}
845+
846+
@override
847+
void dispose() {
848+
_controller.dispose();
849+
super.dispose();
850+
}
851+
852+
DataSource restoreDataSource() {
853+
final DataSource dataSource = DataSource(
854+
sourceType: DataSourceType.network,
855+
uri: 'https://media.w3.org/2010/05/bunny/trailer.mp4',
856+
);
857+
return dataSource;
858+
}
859+
860+
int restoreTime() {
861+
/// if resumeTime >= 0 , it will restore from resumeTime
862+
/// if resumeTime is not set or <0, it will restore from the time when suspend is called
863+
const int resumeTime = 0;
864+
return resumeTime;
865+
}
866+
867+
@override
868+
Widget build(BuildContext context) {
869+
return SingleChildScrollView(
870+
child: Column(
871+
children: <Widget>[
872+
Container(padding: const EdgeInsets.only(top: 20.0)),
873+
const Text('ChangeURLTest'),
874+
Container(
875+
padding: const EdgeInsets.all(20),
876+
child: AspectRatio(
877+
aspectRatio: _controller.value.aspectRatio,
878+
child: Stack(
879+
alignment: Alignment.bottomCenter,
880+
children: <Widget>[
881+
VideoPlayer(_controller),
882+
ClosedCaption(text: _controller.value.caption.text),
883+
_ControlsOverlay(controller: _controller),
884+
VideoProgressIndicator(_controller, allowScrubbing: true),
885+
],
886+
),
887+
),
888+
),
889+
],
890+
),
891+
);
892+
}
893+
}

packages/video_player_avplay/lib/src/messages.g.dart

Lines changed: 91 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -467,57 +467,60 @@ class _VideoPlayerAvplayApiCodec extends StandardMessageCodec {
467467
} else if (value is CreateMessage) {
468468
buffer.putUint8(129);
469469
writeValue(buffer, value.encode());
470-
} else if (value is DashPropertyMapMessage) {
470+
} else if (value is CreateMessage) {
471471
buffer.putUint8(130);
472472
writeValue(buffer, value.encode());
473-
} else if (value is DashPropertyTypeListMessage) {
473+
} else if (value is DashPropertyMapMessage) {
474474
buffer.putUint8(131);
475475
writeValue(buffer, value.encode());
476-
} else if (value is DisplayModeMessage) {
476+
} else if (value is DashPropertyTypeListMessage) {
477477
buffer.putUint8(132);
478478
writeValue(buffer, value.encode());
479-
} else if (value is DurationMessage) {
479+
} else if (value is DisplayModeMessage) {
480480
buffer.putUint8(133);
481481
writeValue(buffer, value.encode());
482-
} else if (value is GeometryMessage) {
482+
} else if (value is DurationMessage) {
483483
buffer.putUint8(134);
484484
writeValue(buffer, value.encode());
485-
} else if (value is LoopingMessage) {
485+
} else if (value is GeometryMessage) {
486486
buffer.putUint8(135);
487487
writeValue(buffer, value.encode());
488-
} else if (value is MixWithOthersMessage) {
488+
} else if (value is LoopingMessage) {
489489
buffer.putUint8(136);
490490
writeValue(buffer, value.encode());
491-
} else if (value is PlaybackSpeedMessage) {
491+
} else if (value is MixWithOthersMessage) {
492492
buffer.putUint8(137);
493493
writeValue(buffer, value.encode());
494-
} else if (value is PlayerMessage) {
494+
} else if (value is PlaybackSpeedMessage) {
495495
buffer.putUint8(138);
496496
writeValue(buffer, value.encode());
497-
} else if (value is PositionMessage) {
497+
} else if (value is PlayerMessage) {
498498
buffer.putUint8(139);
499499
writeValue(buffer, value.encode());
500-
} else if (value is RotationMessage) {
500+
} else if (value is PositionMessage) {
501501
buffer.putUint8(140);
502502
writeValue(buffer, value.encode());
503-
} else if (value is SelectedTracksMessage) {
503+
} else if (value is RotationMessage) {
504504
buffer.putUint8(141);
505505
writeValue(buffer, value.encode());
506-
} else if (value is StreamingPropertyMessage) {
506+
} else if (value is SelectedTracksMessage) {
507507
buffer.putUint8(142);
508508
writeValue(buffer, value.encode());
509-
} else if (value is StreamingPropertyTypeMessage) {
509+
} else if (value is StreamingPropertyMessage) {
510510
buffer.putUint8(143);
511511
writeValue(buffer, value.encode());
512-
} else if (value is TrackMessage) {
512+
} else if (value is StreamingPropertyTypeMessage) {
513513
buffer.putUint8(144);
514514
writeValue(buffer, value.encode());
515-
} else if (value is TrackTypeMessage) {
515+
} else if (value is TrackMessage) {
516516
buffer.putUint8(145);
517517
writeValue(buffer, value.encode());
518-
} else if (value is VolumeMessage) {
518+
} else if (value is TrackTypeMessage) {
519519
buffer.putUint8(146);
520520
writeValue(buffer, value.encode());
521+
} else if (value is VolumeMessage) {
522+
buffer.putUint8(147);
523+
writeValue(buffer, value.encode());
521524
} else {
522525
super.writeValue(buffer, value);
523526
}
@@ -531,38 +534,40 @@ class _VideoPlayerAvplayApiCodec extends StandardMessageCodec {
531534
case 129:
532535
return CreateMessage.decode(readValue(buffer)!);
533536
case 130:
534-
return DashPropertyMapMessage.decode(readValue(buffer)!);
537+
return CreateMessage.decode(readValue(buffer)!);
535538
case 131:
536-
return DashPropertyTypeListMessage.decode(readValue(buffer)!);
539+
return DashPropertyMapMessage.decode(readValue(buffer)!);
537540
case 132:
538-
return DisplayModeMessage.decode(readValue(buffer)!);
541+
return DashPropertyTypeListMessage.decode(readValue(buffer)!);
539542
case 133:
540-
return DurationMessage.decode(readValue(buffer)!);
543+
return DisplayModeMessage.decode(readValue(buffer)!);
541544
case 134:
542-
return GeometryMessage.decode(readValue(buffer)!);
545+
return DurationMessage.decode(readValue(buffer)!);
543546
case 135:
544-
return LoopingMessage.decode(readValue(buffer)!);
547+
return GeometryMessage.decode(readValue(buffer)!);
545548
case 136:
546-
return MixWithOthersMessage.decode(readValue(buffer)!);
549+
return LoopingMessage.decode(readValue(buffer)!);
547550
case 137:
548-
return PlaybackSpeedMessage.decode(readValue(buffer)!);
551+
return MixWithOthersMessage.decode(readValue(buffer)!);
549552
case 138:
550-
return PlayerMessage.decode(readValue(buffer)!);
553+
return PlaybackSpeedMessage.decode(readValue(buffer)!);
551554
case 139:
552-
return PositionMessage.decode(readValue(buffer)!);
555+
return PlayerMessage.decode(readValue(buffer)!);
553556
case 140:
554-
return RotationMessage.decode(readValue(buffer)!);
557+
return PositionMessage.decode(readValue(buffer)!);
555558
case 141:
556-
return SelectedTracksMessage.decode(readValue(buffer)!);
559+
return RotationMessage.decode(readValue(buffer)!);
557560
case 142:
558-
return StreamingPropertyMessage.decode(readValue(buffer)!);
561+
return SelectedTracksMessage.decode(readValue(buffer)!);
559562
case 143:
560-
return StreamingPropertyTypeMessage.decode(readValue(buffer)!);
563+
return StreamingPropertyMessage.decode(readValue(buffer)!);
561564
case 144:
562-
return TrackMessage.decode(readValue(buffer)!);
565+
return StreamingPropertyTypeMessage.decode(readValue(buffer)!);
563566
case 145:
564-
return TrackTypeMessage.decode(readValue(buffer)!);
567+
return TrackMessage.decode(readValue(buffer)!);
565568
case 146:
569+
return TrackTypeMessage.decode(readValue(buffer)!);
570+
case 147:
566571
return VolumeMessage.decode(readValue(buffer)!);
567572
default:
568573
return super.readValueOfType(type, buffer);
@@ -1164,6 +1169,59 @@ class VideoPlayerAvplayApi {
11641169
}
11651170
}
11661171

1172+
Future<void> suspend(int arg_playerId) async {
1173+
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
1174+
'dev.flutter.pigeon.video_player_avplay.VideoPlayerAvplayApi.suspend',
1175+
codec,
1176+
binaryMessenger: _binaryMessenger,
1177+
);
1178+
final List<Object?>? replyList =
1179+
await channel.send(<Object?>[arg_playerId]) as List<Object?>?;
1180+
if (replyList == null) {
1181+
throw PlatformException(
1182+
code: 'channel-error',
1183+
message: 'Unable to establish connection on channel.',
1184+
);
1185+
} else if (replyList.length > 1) {
1186+
throw PlatformException(
1187+
code: replyList[0]! as String,
1188+
message: replyList[1] as String?,
1189+
details: replyList[2],
1190+
);
1191+
} else {
1192+
return;
1193+
}
1194+
}
1195+
1196+
Future<void> restore(
1197+
int arg_playerId,
1198+
CreateMessage? arg_msg,
1199+
int arg_resumeTime,
1200+
) async {
1201+
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
1202+
'dev.flutter.pigeon.video_player_avplay.VideoPlayerAvplayApi.restore',
1203+
codec,
1204+
binaryMessenger: _binaryMessenger,
1205+
);
1206+
final List<Object?>? replyList =
1207+
await channel.send(<Object?>[arg_playerId, arg_msg, arg_resumeTime])
1208+
as List<Object?>?;
1209+
if (replyList == null) {
1210+
throw PlatformException(
1211+
code: 'channel-error',
1212+
message: 'Unable to establish connection on channel.',
1213+
);
1214+
} else if (replyList.length > 1) {
1215+
throw PlatformException(
1216+
code: replyList[0]! as String,
1217+
message: replyList[1] as String?,
1218+
details: replyList[2],
1219+
);
1220+
} else {
1221+
return;
1222+
}
1223+
}
1224+
11671225
Future<bool> setData(DashPropertyMapMessage arg_msg) async {
11681226
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
11691227
'dev.flutter.pigeon.video_player_avplay.VideoPlayerAvplayApi.setData',

0 commit comments

Comments
 (0)