I created a custom VideoPlayer BUT when I navigate to other page, the sound of the video will not go away unless I start reproducing other video.
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/custom_code/actions/index.dart'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:http/http.dart'
as http; // Importación para realizar solicitudes HTTP
import 'dart:convert'; // Importación para manejar JSON
import 'package:flutter/services.dart'; // Importación para controlar la orientación del dispositivo
class YtAndVimeoWebViewPlayer extends StatefulWidget {
const YtAndVimeoWebViewPlayer({
Key? key,
this.width,
this.height,
this.videoUrl,
this.accessTokenVimeo,
}) : super(key: key);
final double? width;
final double? height;
final String? videoUrl;
final String? accessTokenVimeo;
@override
_YtAndVimeoWebViewPlayerState createState() =>
_YtAndVimeoWebViewPlayerState();
}
class _YtAndVimeoWebViewPlayerState extends State<YtAndVimeoWebViewPlayer> {
late String embedUrl = '';
InAppWebViewController? webViewController; // Controlador para el WebView
@override
void initState() {
super.initState();
analyzeVideoUrl(widget.videoUrl!);
}
Future<void> analyzeVideoUrl(String videoUrl) async {
if (videoUrl.contains('youtube.com') || videoUrl.contains('youtu.be')) {
final videoId = extractYouTubeVideoId(videoUrl);
embedUrl =
'https://www.youtube.com/embed/$videoId?autoplay=1&fullscreen=1';
} else if (videoUrl.contains('vimeo.com')) {
final videoId = extractVimeoVideoId(videoUrl);
final vimeoEmbedUrl =
await getVimeoEmbedHtml(videoId, widget.accessTokenVimeo!);
embedUrl = vimeoEmbedUrl + '?autoplay=1&muted=0&fullscreen=1';
}
if (mounted) {
setState(() {});
}
}
String extractYouTubeVideoId(String youtubeUrl) {
final regExp1 = RegExp(r'youtu\.be/([a-zA-Z0-9_-]+)');
final regExp2 = RegExp(r'v=([a-zA-Z0-9_-]+)');
final regExp3 = RegExp(r'youtu\.be/([a-zA-Z0-9_-]+)\?');
final match1 = regExp1.firstMatch(youtubeUrl);
final match2 = regExp2.firstMatch(youtubeUrl);
final match3 = regExp3.firstMatch(youtubeUrl);
if (match1 != null && match1.groupCount >= 1) {
return match1.group(1)!;
} else if (match2 != null && match2.groupCount >= 1) {
return match2.group(1)!;
} else if (match3 != null && match3.groupCount >= 1) {
return match3.group(1)!;
}
throw Exception('Failed to extract YouTube video ID');
}
String extractVimeoVideoId(String vimeoUrl) {
final regExp = RegExp(r'/(\d+)');
final match = regExp.firstMatch(vimeoUrl);
if (match != null && match.groupCount >= 1) {
return match.group(1)!;
}
throw Exception('Failed to extract Vimeo video ID');
}
Future<String> getVimeoEmbedHtml(String videoId, String accessToken) async {
final url = 'https://api.vimeo.com/videos/$videoId';
final response = await http.get(
Uri.parse(url),
headers: {
'Authorization': 'Bearer $accessToken',
},
);
if (response.statusCode == 200) {
final jsonData = json.decode(response.body);
if (jsonData != null &&
jsonData.containsKey('embed') &&
jsonData['embed'].containsKey('html')) {
final embedHtml = jsonData['player_embed_url'];
print('this is vimeo embed url = $embedHtml');
return embedHtml;
} else {
throw Exception(
'Vimeo API response does not contain the expected data structure.');
}
} else {
throw Exception(
'Failed to fetch Vimeo embed HTML. Status code: ${response.statusCode}');
}
}
@override
Widget build(BuildContext context) {
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
return Scaffold(
body: SafeArea(
child: Center(
child: embedUrl.isNotEmpty
? _buildWebView(isPortrait)
: CircularProgressIndicator(
backgroundColor: Colors.black,
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFEBA317)),
),
),
),
);
}
Widget _buildWebView(bool isPortrait) {
return InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse(embedUrl),
),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
mediaPlaybackRequiresUserGesture: false,
javaScriptEnabled: true,
),
),
onWebViewCreated: (controller) {
webViewController = controller; // Asigna el controlador de WebView
},
onEnterFullscreen: (controller) async {
await SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight
]);
},
onExitFullscreen: (controller) async {
await SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
},
onLoadError: (controller, url, code, message) {
print('WebView Error - URL: $url, Code: $code, Message: $message');
},
);
}
@override
void dispose() {
// Enviar JavaScript para pausar el video
webViewController?.evaluateJavascript(source: '''
var video = document.querySelector('video');
if (video) {
video.pause();
}
''');
super.dispose();
}
}