From 6942518b4b07a7ea628f9ad92d0ce6ef5ce1b5b6 Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Fri, 17 Apr 2026 14:14:58 +0200 Subject: [PATCH] Update Section video to support youtube, vimeo and local video (to be tested) --- lib/Screens/Video/video_view.dart | 151 ++++++++++++++++-------------- 1 file changed, 80 insertions(+), 71 deletions(-) diff --git a/lib/Screens/Video/video_view.dart b/lib/Screens/Video/video_view.dart index 676f306..32034e2 100644 --- a/lib/Screens/Video/video_view.dart +++ b/lib/Screens/Video/video_view.dart @@ -1,12 +1,22 @@ -import 'dart:convert'; - -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:manager_api_new/api.dart'; +import 'package:tablet_app/Components/video_viewer.dart'; import 'package:tablet_app/constants.dart'; -import 'package:youtube_player_flutter/youtube_player_flutter.dart'; +import 'package:webview_flutter/webview_flutter.dart'; import 'package:youtube_player_iframe/youtube_player_iframe.dart' as iframe; -//import 'package:youtube_player_flutter/youtube_player_flutter.dart'; + +enum _VideoSourceType { youtube, vimeo, direct } + +_VideoSourceType _detectSourceType(String url) { + if (url.contains('youtube.com') || url.contains('youtu.be')) return _VideoSourceType.youtube; + if (url.contains('vimeo.com')) return _VideoSourceType.vimeo; + return _VideoSourceType.direct; +} + +String? _extractVimeoId(String url) { + final match = RegExp(r'vimeo\.com/(?:.*?/)?(\d+)').firstMatch(url); + return match?.group(1); +} class VideoView extends StatefulWidget { final VideoDTO section; @@ -17,84 +27,83 @@ class VideoView extends StatefulWidget { } class _VideoView extends State { - iframe.YoutubePlayer? _videoViewWeb; - YoutubePlayer? _videoView; - VideoDTO? videoDTO; + iframe.YoutubePlayerController? _youtubeController; + WebViewController? _vimeoController; + _VideoSourceType? _sourceType; + + static const _browserUserAgent = + 'Mozilla/5.0 (Linux; Android 10; Tablet) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; @override void initState() { - //print(widget.section!.data); - //videoDTO = VideoDTO.fromJson(jsonDecode(widget.section!.data!)); - //print(videoDTO); - videoDTO= widget.section; + super.initState(); + final source = widget.section.source_; + if (source == null || source.isEmpty) return; - String? videoId; - if (videoDTO!.source_ != null && videoDTO!.source_!.length > 0 ) { - videoId = YoutubePlayer.convertUrlToId(videoDTO!.source_!); + _sourceType = _detectSourceType(source); - if (true) { - final _controllerWeb = iframe.YoutubePlayerController( - params: iframe.YoutubePlayerParams( - mute: false, - showControls: true, - showFullscreenButton: false, - loop: true, - showVideoAnnotations: false, - strictRelatedVideos: false, - enableKeyboard: false, - enableCaption: false, - pointerEvents: iframe.PointerEvents.auto - ), - ); - - _controllerWeb.loadVideo(videoDTO!.source_!); - - _videoViewWeb = iframe.YoutubePlayer( - controller: _controllerWeb, - //showVideoProgressIndicator: false, - /*progressIndicatorColor: Colors.amber, - progressColors: ProgressBarColors( - playedColor: Colors.amber, - handleColor: Colors.amberAccent, - ),*/ - ); - } else { - videoId = YoutubePlayer.convertUrlToId(videoDTO!.source_!); - YoutubePlayerController _controller = YoutubePlayerController( - initialVideoId: videoId!, - flags: YoutubePlayerFlags( - autoPlay: true, - controlsVisibleAtStart: false, - loop: true, - hideControls: false, - hideThumbnail: false, - ), - ); - - - _videoView = YoutubePlayer( - controller: _controller, - //showVideoProgressIndicator: false, - progressIndicatorColor: Colors.amber, - progressColors: ProgressBarColors( - playedColor: Colors.amber, - handleColor: Colors.amberAccent, - ), - ); + if (_sourceType == _VideoSourceType.youtube) { + _youtubeController = iframe.YoutubePlayerController( + params: iframe.YoutubePlayerParams( + mute: false, + showControls: true, + showFullscreenButton: false, + loop: true, + showVideoAnnotations: false, + strictRelatedVideos: false, + enableKeyboard: false, + enableCaption: false, + pointerEvents: iframe.PointerEvents.auto, + userAgent: _browserUserAgent, + ), + ); + _youtubeController!.loadVideo(source); + } else if (_sourceType == _VideoSourceType.vimeo) { + final vimeoId = _extractVimeoId(source); + if (vimeoId != null) { + _vimeoController = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setUserAgent(_browserUserAgent) + ..loadRequest(Uri.parse('https://player.vimeo.com/video/$vimeoId')); } - super.initState(); } } @override void dispose() { - _videoView = null; - _videoViewWeb = null; + _youtubeController?.close(); super.dispose(); } @override - Widget build(BuildContext context) => videoDTO!.source_ != null && videoDTO!.source_!.length > 0 ? - (true ? _videoViewWeb! : _videoView!): - Center(child: Text("La vidéo ne peut pas être affichée, l'url est incorrecte", style: new TextStyle(fontSize: kNoneInfoOrIncorrect))); -} \ No newline at end of file + Widget build(BuildContext context) { + final source = widget.section.source_; + if (source == null || source.isEmpty) { + return Center( + child: Text( + "La vidéo ne peut pas être affichée, l'url est incorrecte", + style: TextStyle(fontSize: kNoneInfoOrIncorrect), + ), + ); + } + + switch (_sourceType) { + case _VideoSourceType.youtube: + return iframe.YoutubePlayer(controller: _youtubeController!); + case _VideoSourceType.vimeo: + if (_vimeoController == null) { + return Center( + child: Text( + "Impossible d'extraire l'identifiant Vimeo depuis l'URL", + style: TextStyle(fontSize: kNoneInfoOrIncorrect), + ), + ); + } + return WebViewWidget(controller: _vimeoController!); + case _VideoSourceType.direct: + return VideoViewer(videoUrl: source, file: null); + default: + return const SizedBox(); + } + } +}