setQuality method
Change video quality
Implementation
Future<void> setQuality(int height) async {
if (_currentManifest == null || _currentVideoId == null) {
if (!kReleaseMode) {
debugPrint(
'YPlayerController: Cannot change quality - no manifest available');
}
return;
}
if (_status == YPlayerStatus.loading) return;
if (_currentQuality == height) return; // No-op if already at this quality
_currentQuality = height;
final currentPosition = _player.state.position;
final wasPlaying = _player.state.playing;
_setStatus(YPlayerStatus.loading);
try {
exp.VideoStreamInfo videoStreamInfo;
if (height == 0) {
videoStreamInfo = withHighestBitrate(_currentManifest!);
} else {
videoStreamInfo = _currentManifest!.videoOnly
.where((s) => s.videoResolution.height == height)
.withHighestBitrate();
}
final audioStreamInfo = _currentManifest!.audioOnly.withHighestBitrate();
// Only switch if the URL is different
final currentUrl = _player.state.playlist.medias.isNotEmpty
? _player.state.playlist.medias.first.uri.toString()
: '';
if (currentUrl == videoStreamInfo.url.toString()) {
_setStatus(wasPlaying ? YPlayerStatus.playing : YPlayerStatus.paused);
return;
}
if (!kReleaseMode) {
debugPrint(
'YPlayerController: Changing quality to ${videoStreamInfo.videoResolution.height}p');
}
await _player.stop();
await _player.open(
Media(videoStreamInfo.url.toString(), start: currentPosition),
play: false);
await Future.delayed(const Duration(milliseconds: 100));
await _player
.setAudioTrack(AudioTrack.uri(audioStreamInfo.url.toString()));
if (wasPlaying) {
play();
}
_setStatus(wasPlaying ? YPlayerStatus.playing : YPlayerStatus.paused);
if (!kReleaseMode) {
debugPrint('YPlayerController: Quality change complete');
}
} catch (e) {
if (!kReleaseMode) {
debugPrint('YPlayerController: Error changing quality: $e');
}
_setStatus(YPlayerStatus.error);
}
}