Skip to content

Commit bb34431

Browse files
committed
[plugin] Added Texture based Video widget for Windows
1 parent 89ecd08 commit bb34431

File tree

5 files changed

+94
-95
lines changed

5 files changed

+94
-95
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ Under progress or planned features (irrespective of order)...
391391

392392
First of all, thanks to the [VideoLAN](https://www.videolan.org) team for creating [libVLC](https://github.com/videolan/vlc) & [libVLC++](https://github.com/videolan/libvlcpp). Really great guys really great at their work.
393393

394+
[@jnschulze](https://github.com/jnschulze) for his awesome contributions to Flutter engine like adding texture support.
395+
394396
Thanks to following members of libVLC community (irrespective of the order) to give me bit of look & advice about how things work:
395397

396398
- [@jeremyVignelles](https://github.com/jeremyVignelles)

lib/dart_vlc.dart

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export 'package:dart_vlc/src/widgets/video.dart';
2222
/// Platform channel for using [Texture] & flutter::TextureRegistrar on Windows.
2323
final MethodChannel _channel = MethodChannel('dart_vlc');
2424

25-
2625
/// A [Player] to open & play a [Media] or [Playlist] from file, network or asset.
2726
///
2827
/// Use [Player] constructor to create a new instance of a [Player].
@@ -50,28 +49,28 @@ final MethodChannel _channel = MethodChannel('dart_vlc');
5049
class Player extends FFI.Player {
5150
int? textureId;
5251

53-
Player({
54-
required int id,
55-
int videoWidth: 0,
56-
int videoHeight: 0,
57-
List<String>? commandlineArguments
58-
}) : super(id: id, videoWidth: videoWidth, videoHeight: videoHeight, commandlineArguments: commandlineArguments) {
52+
Player(
53+
{required int id,
54+
int videoWidth: 0,
55+
int videoHeight: 0,
56+
List<String>? commandlineArguments})
57+
: super(
58+
id: id,
59+
videoWidth: videoWidth,
60+
videoHeight: videoHeight,
61+
commandlineArguments: commandlineArguments) {
5962
if (this.videoHeight > 0 && this.videoWidth > 0 && Platform.isWindows) {
6063
() async {
61-
this.textureId = await _channel.invokeMethod(
62-
'Player.onVideo',
63-
{
64-
'playerId': this.id,
65-
'videoWidth': this.videoWidth,
66-
'videoHeight': this.videoHeight
67-
}
68-
);
64+
this.textureId = await _channel.invokeMethod('Player.onVideo', {
65+
'playerId': this.id,
66+
'videoWidth': this.videoWidth,
67+
'videoHeight': this.videoHeight
68+
});
6969
}();
7070
}
7171
}
7272
}
7373

74-
7574
/// Initializes the DartVLC plugin.
7675
///
7776
/// ```dart
@@ -86,13 +85,13 @@ abstract class DartVLC {
8685
FFI.videoFrameCallback = (int playerId, Uint8List videoFrame) {
8786
if (videoStreamControllers[playerId] != null &&
8887
FFI.players[playerId] != null) {
89-
if (!videoStreamControllers[playerId]!.isClosed) {
90-
videoStreamControllers[playerId]!.add(new VideoFrame(
88+
if (!videoStreamControllers[playerId]!.isClosed) {
89+
videoStreamControllers[playerId]!.add(new VideoFrame(
9190
playerId: playerId,
9291
videoWidth: FFI.players[playerId]!.videoWidth,
9392
videoHeight: FFI.players[playerId]!.videoHeight,
9493
byteArray: videoFrame));
95-
}
94+
}
9695
}
9796
};
9897
if (Platform.isWindows) {

lib/src/experimental/video.dart

Lines changed: 0 additions & 38 deletions
This file was deleted.

lib/src/widgets/controls.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,11 @@ class ControlState extends State<Control> with SingleTickerProviderStateMixin {
6060
super.initState();
6161
this.playPauseController = new AnimationController(
6262
vsync: this, duration: Duration(milliseconds: 400));
63-
this.playPauseStream = players[widget.playerId]!.playbackStream.listen((event) => this.setPlaybackMode(event.isPlaying));
64-
if (players[widget.playerId]!.playback.isPlaying) this.playPauseController.forward();
63+
this.playPauseStream = players[widget.playerId]!
64+
.playbackStream
65+
.listen((event) => this.setPlaybackMode(event.isPlaying));
66+
if (players[widget.playerId]!.playback.isPlaying)
67+
this.playPauseController.forward();
6568
}
6669

6770
@override

lib/src/widgets/video.dart

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// ignore_for_file: implementation_imports
22
import 'dart:async';
3+
import 'dart:io';
34
import 'dart:typed_data';
45
import 'dart:ui' as ui;
56
import 'package:flutter/material.dart';
6-
import 'package:dart_vlc_ffi/src/player.dart';
7+
import 'package:dart_vlc_ffi/src/player.dart' hide Player;
8+
import 'package:dart_vlc/dart_vlc.dart';
79
import 'package:dart_vlc/src/widgets/controls.dart';
810

911
/// Internally used map to keep [GlobalKey]s for [Video]'s [ControlState]s.
@@ -69,6 +71,9 @@ class Video extends StatefulWidget {
6971
/// Scale.
7072
final double scale;
7173

74+
/// Filter quality.
75+
final FilterQuality filterQuality;
76+
7277
// Built-In video controls.
7378
final bool showControls;
7479

@@ -127,6 +132,7 @@ class Video extends StatefulWidget {
127132
this.progressBarThumbGlowRadius = 15.0,
128133
this.showTimeLeft = false,
129134
this.progressBarTextStyle = const TextStyle(),
135+
this.filterQuality = FilterQuality.low,
130136
Key? key,
131137
}) : super(key: key);
132138

@@ -155,58 +161,85 @@ class VideoState extends State<Video> {
155161
height: widget.height,
156162
width: widget.width,
157163
scale: widget.scale,
158-
filterQuality: FilterQuality.low,
164+
filterQuality: widget.filterQuality,
159165
);
160166
}
161167

162168
@override
163169
Future<void> dispose() async {
164170
super.dispose();
165-
await videoStreamControllers[widget.playerId]?.close();
171+
if (Platform.isWindows) {
172+
} else {
173+
await videoStreamControllers[widget.playerId]?.close();
174+
}
166175
}
167176

168177
@override
169178
void initState() {
170179
super.initState();
171-
if (widget.showControls) controls[widget.playerId] = this.controlKey;
172-
videoStreamControllers[widget.playerId] =
173-
new StreamController<VideoFrame>.broadcast();
174-
videoStreamControllers[widget.playerId]?.stream
175-
.listen((VideoFrame videoFrame) async {
176-
this.videoFrameRawImage = await this.getVideoFrameRawImage(videoFrame);
177-
if (this.mounted) {
178-
this.setState(() {});
179-
}
180-
});
180+
if (Platform.isWindows) {
181+
} else {
182+
if (widget.showControls) controls[widget.playerId] = this.controlKey;
183+
videoStreamControllers[widget.playerId] =
184+
new StreamController<VideoFrame>.broadcast();
185+
videoStreamControllers[widget.playerId]
186+
?.stream
187+
.listen((VideoFrame videoFrame) async {
188+
this.videoFrameRawImage = await this.getVideoFrameRawImage(videoFrame);
189+
if (this.mounted) {
190+
this.setState(() {});
191+
}
192+
});
193+
}
181194
}
182195

183196
@override
184197
Widget build(BuildContext context) {
185198
if (widget.showControls) {
186199
return Control(
187-
key: this.controlKey,
188-
playerId: widget.playerId,
189-
height: widget.height,
190-
width: widget.width,
191-
progressBarThumbRadius: widget.progressBarThumbRadius,
192-
progressBarThumbGlowRadius: widget.progressBarThumbGlowRadius,
193-
progressBarActiveColor: widget.progressBarActiveColor,
194-
progressBarInactiveColor: widget.progressBarInactiveColor,
195-
progressBarThumbColor: widget.progressBarThumbColor,
196-
progressBarThumbGlowColor: widget.progressBarThumbGlowColor,
197-
volumeActiveColor: widget.volumeActiveColor,
198-
volumeInactiveColor: widget.volumeInactiveColor,
199-
volumeBackgroundColor: widget.volumeBackgroundColor,
200-
volumeThumbColor: widget.volumeThumbColor,
201-
showTimeLeft: widget.showTimeLeft,
202-
progressBarTextStyle: widget.progressBarTextStyle,
203-
child: this.videoFrameRawImage ??
204-
Container(
205-
color: Colors.black,
206-
height: widget.height,
207-
width: widget.width,
208-
),
209-
);
200+
key: this.controlKey,
201+
playerId: widget.playerId,
202+
height: widget.height,
203+
width: widget.width,
204+
progressBarThumbRadius: widget.progressBarThumbRadius,
205+
progressBarThumbGlowRadius: widget.progressBarThumbGlowRadius,
206+
progressBarActiveColor: widget.progressBarActiveColor,
207+
progressBarInactiveColor: widget.progressBarInactiveColor,
208+
progressBarThumbColor: widget.progressBarThumbColor,
209+
progressBarThumbGlowColor: widget.progressBarThumbGlowColor,
210+
volumeActiveColor: widget.volumeActiveColor,
211+
volumeInactiveColor: widget.volumeInactiveColor,
212+
volumeBackgroundColor: widget.volumeBackgroundColor,
213+
volumeThumbColor: widget.volumeThumbColor,
214+
showTimeLeft: widget.showTimeLeft,
215+
progressBarTextStyle: widget.progressBarTextStyle,
216+
child: Platform.isWindows
217+
? (
218+
/* Using flutter::TextureRegistrar for Windows. */
219+
((players[widget.playerId]! as Player).textureId != null)
220+
? Container(
221+
width: widget.width,
222+
height: widget.height,
223+
color: Colors.black,
224+
child: Texture(
225+
textureId: (players[widget.playerId]! as Player)
226+
.textureId!,
227+
filterQuality: widget.filterQuality,
228+
),
229+
)
230+
: Container(
231+
width: widget.width,
232+
height: widget.height,
233+
color: Colors.black,
234+
))
235+
: (
236+
/* Using NativePorts for Linux. */
237+
this.videoFrameRawImage ??
238+
Container(
239+
color: Colors.black,
240+
height: widget.height,
241+
width: widget.width,
242+
)));
210243
} else {
211244
return this.videoFrameRawImage ??
212245
Container(

0 commit comments

Comments
 (0)