From dde3d020d924371bf4097cf6d7d1cb11a2884ece Mon Sep 17 00:00:00 2001 From: Sheikh Haziq Date: Sat, 4 Jan 2025 22:03:04 +0530 Subject: [PATCH] fixed problems with playback error. Also improved loading time at seek. --- android/app/build.gradle | 18 +++---- lib/app_config.dart | 2 +- lib/screens/home_screen/section_item.dart | 4 ++ lib/services/custom_audio_stream.dart | 60 ++++++++++++++++------- lib/services/media_player.dart | 4 +- lib/services/stream_client.dart | 5 +- pubspec.lock | 11 +++-- pubspec.yaml | 13 +++-- 8 files changed, 73 insertions(+), 44 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 0d7a53f..103a868 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -47,20 +47,20 @@ android { versionCode = flutterVersionCode.toInteger() versionName = flutterVersionName } -// signingConfigs { -// release { -// keyAlias keystoreProperties['keyAlias'] -// keyPassword keystoreProperties['keyPassword'] -// storeFile file(keystoreProperties['storeFile']) -// storePassword keystoreProperties['storePassword'] -// } -// } + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile file(keystoreProperties['storeFile']) + storePassword keystoreProperties['storePassword'] + } + } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.debug + signingConfig = signingConfigs.release } } } diff --git a/lib/app_config.dart b/lib/app_config.dart index 24860e6..56831e4 100644 --- a/lib/app_config.dart +++ b/lib/app_config.dart @@ -1,4 +1,4 @@ -AppConfig appConfig = AppConfig(version: 34, codeName: '2.0.9'); +AppConfig appConfig = AppConfig(version: 35, codeName: '2.0.10'); class AppConfig { int version; diff --git a/lib/screens/home_screen/section_item.dart b/lib/screens/home_screen/section_item.dart index 9f91a68..6c5fa9b 100644 --- a/lib/screens/home_screen/section_item.dart +++ b/lib/screens/home_screen/section_item.dart @@ -278,6 +278,10 @@ class SongTile extends StatelessWidget { )); } else { await GetIt.I().playSong(Map.from(song)); + + // final s = GetIt.I(); + // await get(Uri.parse( + // 'http://${s.address.host}:${s.port}/stream?videoId=${song['videoId']}')); } }, onSecondaryTap: () { diff --git a/lib/services/custom_audio_stream.dart b/lib/services/custom_audio_stream.dart index ccdab43..749cd45 100644 --- a/lib/services/custom_audio_stream.dart +++ b/lib/services/custom_audio_stream.dart @@ -1,20 +1,19 @@ import 'dart:async'; - +import 'package:gyawun/services/stream_client.dart'; import 'package:just_audio/just_audio.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart'; -import 'stream_client.dart'; - -YoutubeExplode ytExplode = YoutubeExplode(); class CustomAudioStream extends StreamAudioSource { + late YoutubeExplode ytExplode; + AudioOnlyStreamInfo? streamInfo; String videoId; String quality; - CustomAudioStream(this.videoId, this.quality, {super.tag}); + CustomAudioStream(this.videoId, this.quality, {super.tag}) { + ytExplode = YoutubeExplode(); + } - @override - Future request([int? start, int? end]) async { - print(videoId); + Future _loadStreamInfo() async { StreamManifest manifest = await ytExplode.videos.streamsClient.getManifest(videoId); @@ -29,22 +28,47 @@ class CustomAudioStream extends StreamAudioSource { } else { qualityIndex = streamInfos.length - 1; } - AudioOnlyStreamInfo streamInfo = streamInfos[qualityIndex]; - start ??= 0; + streamInfo = streamInfos[qualityIndex]; + } + + @override + Future request([int? start, int? end]) async { + if (streamInfo == null) { + await _loadStreamInfo(); + } - end ??= (streamInfo.isThrottled + start ??= 0; + end ??= (streamInfo!.isThrottled ? (start + 10379935) - : streamInfo.size.totalBytes); - if (end > streamInfo.size.totalBytes) { - end = streamInfo.size.totalBytes; + : streamInfo!.size.totalBytes); + if (end > streamInfo!.size.totalBytes) { + end = streamInfo!.size.totalBytes; } + + bool isFirstChunk = (start == 0); + if (isFirstChunk) { + final e = start + (1024 * 100); + // Send a small chunk (e.g., 100 KB) for the first request + end = e < streamInfo!.size.totalBytes ? e : end; + } + // var byteRange = 'bytes=$start-$end'; + // var url = streamInfo!.url; + // var headers = { + // HttpHeaders.contentTypeHeader: streamInfo!.codec.type, + // HttpHeaders.rangeHeader: byteRange, + // }; + // var request = http.Request('GET', url)..headers.addAll(headers); + + // final response = await request.send(); + final response = + AudioStreamClient().getAudioStream(streamInfo, start: start, end: end); + return StreamAudioResponse( - sourceLength: streamInfo.size.totalBytes, + sourceLength: streamInfo!.size.totalBytes, contentLength: end - start, offset: start, - stream: AudioStreamClient() - .getAudioStream(streamInfo, start: start, end: end), - contentType: streamInfo.codec.type, + stream: response, + contentType: streamInfo!.codec.type, ); } } diff --git a/lib/services/media_player.dart b/lib/services/media_player.dart index 2764e4a..b09dfa0 100644 --- a/lib/services/media_player.dart +++ b/lib/services/media_player.dart @@ -292,8 +292,8 @@ class MediaPlayer extends ChangeNotifier { if (song['videoId'] != null) { await _player.pause(); await _playlist.clear(); - - await _playlist.add(await _getAudioSource(song)); + final source = await _getAudioSource(song); + await _playlist.add(source); await _player.load(); _player.play(); if (autoFetch == true && song['status'] != 'DOWNLOADED') { diff --git a/lib/services/stream_client.dart b/lib/services/stream_client.dart index 6ef5347..d6cd7d4 100644 --- a/lib/services/stream_client.dart +++ b/lib/services/stream_client.dart @@ -41,10 +41,7 @@ class AudioStreamClient { try { final response = await retry(this, () async { final from = bytesCount; - final to = (streamInfo.isThrottled - ? (bytesCount + 10379935) - : streamInfo.size.totalBytes) - - 1; + final to = end - 1; late final http.Request request; if (url.queryParameters['c'] == 'ANDROID') { diff --git a/pubspec.lock b/pubspec.lock index 7c0360f..17c8156 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1430,11 +1430,12 @@ packages: youtube_explode_dart: dependency: "direct main" description: - name: youtube_explode_dart - sha256: "51ca5b2c03bf56060143d4f87df90ec3227592d7ae8a8003532533ae019d4291" - url: "https://pub.dev" - source: hosted - version: "2.3.6" + path: "." + ref: e519db6 + resolved-ref: e519db65ad0b0a40b12f69285932f9db509da3cf + url: "https://github.com/Hexer10/youtube_explode_dart.git" + source: git + version: "2.3.7" sdks: dart: ">=3.5.0 <4.0.0" flutter: ">=3.27.0" diff --git a/pubspec.yaml b/pubspec.yaml index 11b206e..f5e6238 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: gyawun description: "A new Flutter project." publish_to: 'none' -version: 2.0.9+34 +version: 2.0.10+35 environment: sdk: '>=3.4.1 <4.0.0' @@ -18,7 +18,10 @@ dependencies: http: ^1.2.2 hive: ^2.2.3 hive_flutter: ^1.1.0 - youtube_explode_dart: ^2.3.6 + youtube_explode_dart: + git: + url: https://github.com/Hexer10/youtube_explode_dart.git + ref: e519db6 expandable_page_view: ^1.0.17 get_it: ^7.7.0 cached_network_image: ^3.3.1 @@ -50,11 +53,11 @@ dependencies: flutter_expandable_fab: ^2.1.0 flutter_lyric: ^2.0.4+6 media_kit_libs_windows_audio: any - just_audio_media_kit: ^2.0.6 - media_kit_native_event_loop: ^1.0.8 + just_audio_media_kit: ^2.0.5 + media_kit_native_event_loop: any flutter_acrylic: ^1.1.4 fluent_ui: ^4.9.2 - window_manager: ^0.4.2 + window_manager: ^0.4.3 receive_sharing_intent: git: url: https://github.com/sheikhhaziq/receive_sharing_intent.git