@@ -148,9 +148,9 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
148148 /// is constructed with.
149149 final DataSourceType dataSourceType;
150150
151- String package;
152- Timer timer ;
153- bool isDisposed = false ;
151+ final String package;
152+ Timer _timer ;
153+ bool _isDisposed = false ;
154154 Completer <void > _creatingCompleter;
155155 StreamSubscription <dynamic > _eventSubscription;
156156 _VideoAppLifeCycleObserver _lifeCycleObserver;
@@ -171,6 +171,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
171171 /// null.
172172 VideoPlayerController .network (this .dataSource)
173173 : dataSourceType = DataSourceType .network,
174+ package = null ,
174175 super (new VideoPlayerValue (duration: null ));
175176
176177 /// Constructs a [VideoPlayerController] playing a video from a file.
@@ -180,8 +181,12 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
180181 VideoPlayerController .file (File file)
181182 : dataSource = 'file://${file .path }' ,
182183 dataSourceType = DataSourceType .file,
184+ package = null ,
183185 super (new VideoPlayerValue (duration: null ));
184186
187+ // Visible for testing.
188+ int get textureId => _textureId;
189+
185190 Future <void > initialize () async {
186191 _lifeCycleObserver = new _VideoAppLifeCycleObserver (this );
187192 _lifeCycleObserver.initialize ();
@@ -231,7 +236,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
231236 break ;
232237 case 'completed' :
233238 value = value.copyWith (isPlaying: false );
234- timer ? .cancel ();
239+ _timer ? .cancel ();
235240 break ;
236241 case 'bufferingUpdate' :
237242 final List <dynamic > values = map['values' ];
@@ -251,7 +256,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
251256 void errorListener (Object obj) {
252257 final PlatformException e = obj;
253258 value = new VideoPlayerValue .erroneous (e.message);
254- timer ? .cancel ();
259+ _timer ? .cancel ();
255260 }
256261
257262 _eventSubscription = _eventChannelFor (_textureId)
@@ -268,9 +273,9 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
268273 Future <void > dispose () async {
269274 if (_creatingCompleter != null ) {
270275 await _creatingCompleter.future;
271- if (! isDisposed ) {
272- isDisposed = true ;
273- timer ? .cancel ();
276+ if (! _isDisposed ) {
277+ _isDisposed = true ;
278+ _timer ? .cancel ();
274279 await _eventSubscription? .cancel ();
275280 await _channel.invokeMethod (
276281 'dispose' ,
@@ -279,7 +284,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
279284 }
280285 _lifeCycleObserver.dispose ();
281286 }
282- isDisposed = true ;
287+ _isDisposed = true ;
283288 super .dispose ();
284289 }
285290
@@ -299,7 +304,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
299304 }
300305
301306 Future <void > _applyLooping () async {
302- if (! value.initialized || isDisposed ) {
307+ if (! value.initialized || _isDisposed ) {
303308 return ;
304309 }
305310 _channel.invokeMethod (
@@ -309,29 +314,29 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
309314 }
310315
311316 Future <void > _applyPlayPause () async {
312- if (! value.initialized || isDisposed ) {
317+ if (! value.initialized || _isDisposed ) {
313318 return ;
314319 }
315320 if (value.isPlaying) {
316321 await _channel.invokeMethod (
317322 'play' ,
318323 < String , dynamic > {'textureId' : _textureId},
319324 );
320- timer = new Timer .periodic (
325+ _timer = new Timer .periodic (
321326 const Duration (milliseconds: 500 ),
322327 (Timer timer) async {
323- if (isDisposed ) {
328+ if (_isDisposed ) {
324329 return ;
325330 }
326331 final Duration newPosition = await position;
327- if (isDisposed ) {
332+ if (_isDisposed ) {
328333 return ;
329334 }
330335 value = value.copyWith (position: newPosition);
331336 },
332337 );
333338 } else {
334- timer ? .cancel ();
339+ _timer ? .cancel ();
335340 await _channel.invokeMethod (
336341 'pause' ,
337342 < String , dynamic > {'textureId' : _textureId},
@@ -340,7 +345,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
340345 }
341346
342347 Future <void > _applyVolume () async {
343- if (! value.initialized || isDisposed ) {
348+ if (! value.initialized || _isDisposed ) {
344349 return ;
345350 }
346351 await _channel.invokeMethod (
@@ -351,7 +356,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
351356
352357 /// The position in the current video.
353358 Future <Duration > get position async {
354- if (isDisposed ) {
359+ if (_isDisposed ) {
355360 return null ;
356361 }
357362 return new Duration (
@@ -363,7 +368,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
363368 }
364369
365370 Future <void > seekTo (Duration moment) async {
366- if (isDisposed ) {
371+ if (_isDisposed ) {
367372 return ;
368373 }
369374 if (moment > value.duration) {
@@ -430,29 +435,48 @@ class VideoPlayer extends StatefulWidget {
430435}
431436
432437class _VideoPlayerState extends State <VideoPlayer > {
433- int textureId;
438+ VoidCallback _listener;
439+ int _textureId;
440+
441+ _VideoPlayerState () {
442+ _listener = () {
443+ final int newTextureId = widget.controller.textureId;
444+ if (newTextureId != _textureId) {
445+ setState (() {
446+ _textureId = newTextureId;
447+ });
448+ }
449+ };
450+ }
434451
435452 @override
436453 void initState () {
437454 super .initState ();
438- textureId = widget.controller._textureId ;
455+ _textureId = widget.controller.textureId ;
439456 // Need to listen for initialization events since the actual texture ID
440457 // becomes available after asynchronous initialization finishes.
441- widget.controller.addListener (() {
442- final int newTextureId = widget.controller._textureId;
443- if (newTextureId != textureId) {
444- setState (() {
445- textureId = newTextureId;
446- });
447- }
448- });
458+ widget.controller.addListener (_listener);
459+ }
460+
461+ @override
462+ void didUpdateWidget (VideoPlayer oldWidget) {
463+ super .didUpdateWidget (oldWidget);
464+ oldWidget.controller.removeListener (_listener);
465+ _textureId = widget.controller.textureId;
466+ widget.controller.addListener (_listener);
467+ }
468+
469+ @override
470+ void deactivate () {
471+ super .deactivate ();
472+ widget.controller.removeListener (_listener);
449473 }
450474
451475 @override
452476 Widget build (BuildContext context) {
453- return textureId == null
477+ return _textureId == null
454478 ? new Container ()
455- : new Texture (textureId: textureId );
479+ : new Texture (textureId: _textureId );
456480 }
457481}
458482
0 commit comments