Skip to content

Commit

Permalink
🐛 fixed signal colliding issue
Browse files Browse the repository at this point in the history
  • Loading branch information
sarbagyastha committed Aug 3, 2024
1 parent d736e9b commit e6dd860
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 32 deletions.
11 changes: 6 additions & 5 deletions packages/youtube_player_iframe/assets/player.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

<body>
<div class="embed-container">
<div id="player"></div>
<div id="<<playerId>>"></div>
</div>

<script>
Expand All @@ -52,7 +52,7 @@
var timerId;

function onYouTubeIframeAPIReady() {
player = new YT.Player("player", {
player = new YT.Player("<<playerId>>", {
host: host,
playerVars: <<playerVars>>,
events: {
Expand Down Expand Up @@ -132,11 +132,12 @@
}

function sendMessage(key, data) {
var message = {}
message[key] = data
var message = {};
message[key] = data;
message['playerId'] = '<<playerId>>';
var messageString = JSON.stringify(message);

sendPlatformMessage(messageString)
sendPlatformMessage(messageString);
}

function getVideoData() {
Expand Down
11 changes: 8 additions & 3 deletions packages/youtube_player_iframe/example/lib/video_list_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import 'package:flutter/material.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';

const List<String> _videoIds = [
'dHuYBB05bYU',
'RpoFTgWRfJ4',
'82u-4xcsyJU',
'j4lDDQTKN8s',
'bmgia-h1qNg',
'Cohbiz2lOQI',
'CoNgsfBbxJk',
'c9gzcPkSdw0',
'UEA_uwpvqtI',
'j61j9X4xCnA',
];

///
Expand Down Expand Up @@ -78,6 +82,7 @@ class _VideoListPageState extends State<VideoListPage> {
aspectRatio: 16 / 9,
enableFullScreenOnVerticalDrag: false,
controller: controller,
keepAlive: true,
);
},
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
YoutubePlayerController({
this.params = const YoutubePlayerParams(),
ValueChanged<YoutubeWebResourceError>? onWebResourceError,
this.key,
}) {
_eventHandler = YoutubePlayerEventHandler(this);

Expand Down Expand Up @@ -57,10 +58,7 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(navigationDelegate)
..setUserAgent(params.userAgent)
..addJavaScriptChannel(
_youtubeJSChannelName,
onMessageReceived: _eventHandler.call,
)
..addJavaScriptChannel(playerId, onMessageReceived: _eventHandler.call)
..enableZoom(false);

final webViewPlatform = webViewController.platform;
Expand All @@ -80,7 +78,7 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
double? startSeconds,
double? endSeconds,
}) {
final controller = YoutubePlayerController(params: params);
final controller = YoutubePlayerController(params: params, key: videoId);

if (autoPlay) {
controller.loadVideoById(
Expand All @@ -99,7 +97,8 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
return controller;
}

final String _youtubeJSChannelName = 'YoutubePlayer';
/// The unique key for the player.
final String? key;

/// Defines player parameters for the youtube player.
final YoutubePlayerParams params;
Expand Down Expand Up @@ -249,7 +248,12 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
/// Loads the player with default [params].
@internal
Future<void> init() async {
await load(params: params, baseUrl: params.origin);
final defaultBaseUrl = kIsWeb ? Uri.base.origin : null;
await load(
params: params,
baseUrl: params.origin ?? defaultBaseUrl,
id: playerId,
);

if (!_initCompleter.isCompleted) _initCompleter.complete();
}
Expand All @@ -260,19 +264,19 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
Future<void> load({
required YoutubePlayerParams params,
String? baseUrl,
String id = 'player',
}) async {
final playerHtml = await rootBundle.loadString(
'packages/youtube_player_iframe/assets/player.html',
);

final platform = kIsWeb ? 'web' : defaultTargetPlatform.name.toLowerCase();
final playerData = {
'playerId': id,
'pointerEvents': params.pointerEvents.name,
'playerVars': params.toJson(),
'platform': platform,
'host': params.origin ?? 'https://www.youtube.com',
};

await webViewController.loadHtmlString(
playerHtml
.replaceFirst('<<pointerEvents>>', params.pointerEvents.name)
.replaceFirst('<<playerVars>>', params.toJson())
.replaceFirst('<<platform>>', platform)
.replaceFirst('<<host>>', params.origin ?? 'https://www.youtube.com'),
await _buildPlayerHTML(playerData),
baseUrl: baseUrl,
);
}
Expand Down Expand Up @@ -323,6 +327,10 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
return data == null ? '' : jsonEncode(data);
}

/// The unique player id.
@internal
String get playerId => 'youtube-${key ?? hashCode}';

/// MetaData for the currently loaded or cued video.
YoutubeMetaData get metadata => _value.metaData;

Expand Down Expand Up @@ -664,10 +672,21 @@ class YoutubePlayerController implements YoutubePlayerIFrameAPI {
return NavigationDecision.prevent;
}

Future<String> _buildPlayerHTML(Map<String, String> data) async {
final playerHtml = await rootBundle.loadString(
'packages/youtube_player_iframe/assets/player.html',
);

return playerHtml.replaceAllMapped(
RegExp(r'<<([a-zA-Z]+)>>'),
(m) => data[m.group(1)] ?? m.group(0)!,
);
}

/// Disposes the resources created by [YoutubePlayerController].
Future<void> close() async {
await stopVideo();
await webViewController.removeJavaScriptChannel(_youtubeJSChannelName);
await webViewController.removeJavaScriptChannel('youtube-$hashCode');
await _eventHandler.videoStateController.close();
await _valueController.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class YoutubePlayerEventHandler {
/// Handles the [javaScriptMessage] from the player iframe and create events.
void call(JavaScriptMessage javaScriptMessage) {
final data = Map.from(jsonDecode(javaScriptMessage.message));
if (data['playerId'] != controller.playerId) return;

for (final entry in data.entries) {
if (entry.key == 'ApiChange') {
Expand Down
2 changes: 1 addition & 1 deletion packages/youtube_player_iframe/lib/src/player_params.dart
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class YoutubePlayerParams {
this.interfaceLanguage = 'en',
this.showVideoAnnotations = true,
this.loop = false,
this.origin = 'https://www.youtube.com',
this.origin,
this.playsInline = true,
this.strictRelatedVideos = false,
this.userAgent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class YoutubePlayer extends StatefulWidget {
@Deprecated('Unused parameter. Use `YoutubePlayerParam.userAgent` instead.')
this.userAgent,
this.enableFullScreenOnVerticalDrag = true,
this.keepAlive = false,
});

/// The [controller] for this player.
Expand Down Expand Up @@ -65,11 +66,15 @@ class YoutubePlayer extends StatefulWidget {
/// Default is true.
final bool enableFullScreenOnVerticalDrag;

/// Whether to keep the state of the player alive when it is not visible.
final bool keepAlive;

@override
State<YoutubePlayer> createState() => _YoutubePlayerState();
}

class _YoutubePlayerState extends State<YoutubePlayer> {
class _YoutubePlayerState extends State<YoutubePlayer>
with AutomaticKeepAliveClientMixin {
late final YoutubePlayerController _controller;

@override
Expand All @@ -91,6 +96,8 @@ class _YoutubePlayerState extends State<YoutubePlayer> {

@override
Widget build(BuildContext context) {
super.build(context);

Widget player = WebViewWidget(
controller: _controller.webViewController,
gestureRecognizers: widget.gestureRecognizers,
Expand Down Expand Up @@ -137,4 +144,7 @@ class _YoutubePlayerState extends State<YoutubePlayer> {

await _controller.init();
}

@override
bool get wantKeepAlive => widget.keepAlive;
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,9 @@ class YoutubePlayerIframeWeb extends PlatformWebViewWidget {
if (channelParams != null) {
window.onMessage.listen(
(event) {
if (channelParams.name == 'YoutubePlayer') {
channelParams.onMessageReceived(
JavaScriptMessage(message: event.data.dartify() as String),
);
}
channelParams.onMessageReceived(
JavaScriptMessage(message: event.data.dartify() as String),
);
},
);
}
Expand Down

0 comments on commit e6dd860

Please sign in to comment.