initialize method
Initializes the player with the given YouTube URL and settings.
This method fetches video information, extracts stream URLs, and sets up the player with the highest quality video and audio streams available.
Implementation
Future<void> initialize(
String youtubeUrl, {
bool autoPlay = true,
double? aspectRatio,
bool allowFullScreen = true,
bool allowMuting = true,
bool chooseBestQuality = true, // <--- Add this flag
}) async {
// Avoid re-initialization if the URL hasn't changed
if (_lastInitializedUrl == youtubeUrl && isInitialized) {
if (!kReleaseMode) {
debugPrint('YPlayerController: Already initialized with this URL');
}
return;
}
_setStatus(YPlayerStatus.loading);
try {
// Use cached manifest if available
exp.StreamManifest manifest;
String videoId;
debugPrint('YPlayerController: Fetching video info for $youtubeUrl');
final video = await _yt.videos.get(youtubeUrl);
videoId = video.id.value;
if (_manifestCache.containsKey(videoId)) {
manifest = _manifestCache[videoId]!;
// Move to most recently used
_manifestCacheOrder.remove(videoId);
_manifestCacheOrder.add(videoId);
} else {
manifest = await _yt.videos.streamsClient.getManifest(video.id);
_cacheManifest(videoId, manifest);
}
// Store manifest and video ID for quality changes later
_currentManifest = manifest;
_currentVideoId = videoId;
// --- Choose best quality for internet if requested ---
if (chooseBestQuality) {
// Run asynchronously so UI is not blocked
Future(() async {
final best = await chooseBestQualityForInternet(manifest);
if (best != _currentQuality) {
_currentQuality = best;
await setQuality(best);
}
});
}
// -----------------------------------------------------
// Get the appropriate video stream based on quality setting
exp.VideoStreamInfo videoStreamInfo;
if (_currentQuality == 0) {
// Auto - highest quality
videoStreamInfo = withHighestBitrate(manifest);
} else {
// Try to find the selected quality, fallback to highest if not available
try {
videoStreamInfo = manifest.videoOnly
.where((s) => s.videoResolution.height == _currentQuality)
.withHighestBitrate();
} catch (e) {
debugPrint('YPlayerController: Selected quality not available, using highest');
videoStreamInfo = withHighestBitrate(manifest);
}
}
final audioStreamInfo = manifest.audioOnly.withHighestBitrate();
if (!kReleaseMode) {
debugPrint('YPlayerController: Video URL: ${videoStreamInfo.url}');
debugPrint('YPlayerController: Audio URL: ${audioStreamInfo.url}');
debugPrint(
'YPlayerController: Selected quality: ${videoStreamInfo.videoResolution.height}p');
}
// Stop any existing playback
if (isInitialized) {
debugPrint('YPlayerController: Stopping previous playback');
await _player.stop();
}
// Open the video stream
await _player.open(Media(videoStreamInfo.url.toString()), play: false);
// Add the audio track
await _player
.setAudioTrack(AudioTrack.uri(audioStreamInfo.url.toString()));
// Add a small delay to ensure everything is set up
await Future.delayed(const Duration(milliseconds: 200));
// Start playback if autoPlay is true
if (autoPlay) {
play();
}
_lastInitializedUrl = youtubeUrl;
_setStatus(autoPlay ? YPlayerStatus.playing : YPlayerStatus.paused);
if (!kReleaseMode) {
debugPrint(
'YPlayerController: Initialization complete. Status: $_status');
}
} catch (e) {
if (!kReleaseMode) {
debugPrint('YPlayerController: Error during initialization: $e');
}
_setStatus(YPlayerStatus.error);
}
}