
commit a80d48e19d05d6b9978cc293d5d3dd460c387d27 Author: Thibault Deckers <thibault.deckers@gmail.com> Date: Mon Apr 20 08:34:50 2020 +0900 video: fixed status check commit d5af7cecd5c14c47b108456777da170052b7754f Author: Thibault Deckers <thibault.deckers@gmail.com> Date: Sun Apr 19 22:13:58 2020 +0900 safer seek commit f84768dd9ac5a70a4489509bd944685298023550 Author: Thibault Deckers <thibault.deckers@gmail.com> Date: Sun Apr 19 22:08:06 2020 +0900 use forked `flutter_ijkplayer` to support content URIs on Android < Q commit fde82bc213b0058cd990af2c7678f46b20c78bd7 Author: Thibault Deckers <thibault.deckers@gmail.com> Date: Sun Apr 19 18:39:18 2020 +0900 packages upgrade commit 14414f32203a5caccdb61902ce75b0d83a1a8656 Author: Thibault Deckers <thibault.deckers@gmail.com> Date: Sun Apr 19 14:57:38 2020 +0900 fixes for flutter_ijkplayer commit 2944d84d9f334bbe54303f7eb3b82a517664e84a Author: Thibault Deckers <thibault.deckers@gmail.com> Date: Fri Apr 17 15:58:29 2020 +0900 draft for flutter_ijkplayer commit 0d82956b8e7e1d4500d09805a5d0fd59d2361ed3 Author: Thibault Deckers <thibault.deckers@gmail.com> Date: Fri Apr 17 13:00:14 2020 +0900 switch from video_player to fijkplayer
124 lines
3.7 KiB
Dart
124 lines
3.7 KiB
Dart
import 'dart:async';
|
|
import 'dart:ui';
|
|
|
|
import 'package:aves/model/image_entry.dart';
|
|
import 'package:aves/widgets/common/image_providers/uri_image_provider.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
|
|
|
|
class AvesVideo extends StatefulWidget {
|
|
final ImageEntry entry;
|
|
final IjkMediaController controller;
|
|
|
|
const AvesVideo({
|
|
Key key,
|
|
@required this.entry,
|
|
@required this.controller,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => AvesVideoState();
|
|
}
|
|
|
|
class AvesVideoState extends State<AvesVideo> {
|
|
final List<StreamSubscription> _subscriptions = [];
|
|
|
|
ImageEntry get entry => widget.entry;
|
|
|
|
IjkMediaController get controller => widget.controller;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_registerWidget(widget);
|
|
}
|
|
|
|
@override
|
|
void didUpdateWidget(AvesVideo oldWidget) {
|
|
super.didUpdateWidget(oldWidget);
|
|
_unregisterWidget(oldWidget);
|
|
_registerWidget(widget);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_unregisterWidget(widget);
|
|
super.dispose();
|
|
}
|
|
|
|
void _registerWidget(AvesVideo widget) {
|
|
_subscriptions.add(widget.controller.playFinishStream.listen(_onPlayFinish));
|
|
}
|
|
|
|
void _unregisterWidget(AvesVideo widget) {
|
|
_subscriptions
|
|
..forEach((sub) => sub.cancel())
|
|
..clear();
|
|
}
|
|
|
|
bool isPlayable(IjkStatus status) => [IjkStatus.prepared, IjkStatus.playing, IjkStatus.pause, IjkStatus.complete].contains(status);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (controller == null) return const SizedBox();
|
|
return StreamBuilder<IjkStatus>(
|
|
stream: widget.controller.ijkStatusStream,
|
|
builder: (context, snapshot) {
|
|
final status = snapshot.data;
|
|
return isPlayable(status)
|
|
? IjkPlayer(
|
|
mediaController: controller,
|
|
controllerWidgetBuilder: (controller) => const SizedBox.shrink(),
|
|
statusWidgetBuilder: (context, controller, status) => const SizedBox.shrink(),
|
|
textureBuilder: (context, controller, info) {
|
|
var id = controller.textureId;
|
|
if (id == null) {
|
|
return AspectRatio(
|
|
aspectRatio: entry.displayAspectRatio,
|
|
child: Container(
|
|
color: Colors.green,
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget child = Container(
|
|
color: Colors.blue,
|
|
child: Texture(
|
|
textureId: id,
|
|
),
|
|
);
|
|
|
|
if (!controller.autoRotate) {
|
|
return child;
|
|
}
|
|
|
|
final degree = entry.catalogMetadata?.videoRotation ?? 0;
|
|
if (degree != 0) {
|
|
child = RotatedBox(
|
|
quarterTurns: degree ~/ 90,
|
|
child: child,
|
|
);
|
|
}
|
|
|
|
child = AspectRatio(
|
|
aspectRatio: entry.displayAspectRatio,
|
|
child: child,
|
|
);
|
|
|
|
return Container(
|
|
child: child,
|
|
alignment: Alignment.center,
|
|
color: Colors.transparent,
|
|
);
|
|
},
|
|
)
|
|
: Image(
|
|
image: UriImage(uri: entry.uri, mimeType: entry.mimeType),
|
|
width: entry.width.toDouble(),
|
|
height: entry.height.toDouble(),
|
|
);
|
|
});
|
|
}
|
|
|
|
void _onPlayFinish(IjkMediaController controller) => controller.seekTo(0);
|
|
}
|