What happened?
Environment:
OS: Windows 11
youtube_explode_dart version: 3.0.5
I'm trying to download audio/video streams to disk. The stream completes without emitting any chunks despite having a valid size (result.size.totalBytes returns the correct value). The file ends up being 0kb.
I verified the issue is not related to writing to disk — writing hardcoded bytes to a file works correctly.
Here's the relevant code:
interact_api.dart
import 'dart:async' show Future, Stream;
import 'package:logkeeper/logkeeper.dart' show LogKeeper;
import 'package:youtube_explode_dart/js_challenge.dart' show BaseEJSSolver;
import 'package:youtube_explode_dart/youtube_explode_dart.dart'
show StreamInfoIterableExt, YoutubeExplode;
import '/utils/file_utils.dart' show cleanInvalidChars;
import 'core_utils.dart' show getDenoSolver;
typedef YouTubeStream = Stream<List<int>>;
typedef YouTubeStreamResult = ({YouTubeStream stream, YoutubeExplode yt});
class InteractApi {
static InteractApi? _instance;
late final BaseEJSSolver _solver;
InteractApi._internal();
static InteractApi get instance {
_instance ??= InteractApi._internal();
return _instance!;
}
static Future<void> initialize() async {
try {
LogKeeper.info('Initializing InteractApi...');
instance._solver = await getDenoSolver();
LogKeeper.info('✓ InteractApi initialized successfully');
} catch (e, stackTrace) {
LogKeeper.critical(
'💀 FATAL: Failed to initialize InteractApi: ${e.toString()}',
);
LogKeeper.critical('Error StackTrace: $stackTrace');
rethrow;
}
}
static Future<String> getTitle(String url) async {
final yt = YoutubeExplode(jsSolver: instance._solver);
try {
final video = await yt.videos.get(url);
return cleanInvalidChars(video.title);
} finally {
yt.close();
}
}
static Future<String> getThumbnailUrl(String url) async {
final yt = YoutubeExplode(jsSolver: instance._solver);
try {
final video = await yt.videos.get(url);
return video.thumbnails.highResUrl;
} finally {
yt.close();
}
}
static Future<YouTubeStreamResult> getAudioStream(String url) async {
final yt = YoutubeExplode(jsSolver: instance._solver);
final manifest = await yt.videos.streams.getManifest(url);
final audioStreams = manifest.audioOnly;
if (audioStreams.isEmpty) {
throw Exception('No audio streams available');
}
final audioInfo = audioStreams.withHighestBitrate();
return (stream: yt.videos.streams.get(audioInfo), yt: yt);
}
static Future<YouTubeStreamResult> getVideoStream(String url) async {
final yt = YoutubeExplode(jsSolver: instance._solver);
final manifest = await yt.videos.streams.getManifest(url);
final videoStreams = manifest.videoOnly;
if (videoStreams.isEmpty) {
throw Exception('No video streams available');
}
final videoInfo = videoStreams.withHighestBitrate();
return (stream: yt.videos.streams.get(videoInfo), yt: yt);
}
}
core_utils.dart
import 'dart:io';
import 'package:flutter/services.dart' show rootBundle;
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart'
show getApplicationSupportDirectory;
import 'package:system_info3/system_info3.dart'
show SysInfo, ProcessorArchitecture;
import 'package:youtube_explode_dart/js_challenge.dart' show BaseEJSSolver;
import 'package:youtube_explode_dart/solvers.dart' show DenoEJSSolver;
import '/constants/paths.dart' show denoExecutables;
Future<String> _prepareDeno(String assetPath) async {
final filename = assetPath.split('/').last;
final dir = await getApplicationSupportDirectory();
final destPath = p.join(dir.path, filename);
final file = File(destPath);
if (!await file.exists()) {
final data = await rootBundle.load(assetPath);
await file.writeAsBytes(data.buffer.asUint8List(), flush: true);
await Process.run('chmod', ['u+x', destPath]);
}
return destPath;
}
Future<BaseEJSSolver> getDenoSolver() async {
final denoAssetPath = switch ((
Platform.operatingSystem,
SysInfo.kernelArchitecture,
)) {
('macos', ProcessorArchitecture.arm64) => denoExecutables['macos-arm64']!,
('macos', ProcessorArchitecture.x86_64) => denoExecutables['macos-x86_64']!,
('windows', _) => denoExecutables['windows']!,
('linux', _) => denoExecutables['linux']!,
(var os, _) => throw Exception('Unsupported OS: $os'),
};
final denoPath = Platform.isWindows
? denoAssetPath
: await _prepareDeno(denoAssetPath);
return await DenoEJSSolver.init(denoExe: denoPath);
}
Stacktrace / error logs.
Package (youtube_explode_dart) version
3.0.5
Checklist
Additional notes
No response
What happened?
Environment:
OS: Windows 11
youtube_explode_dart version: 3.0.5
I'm trying to download audio/video streams to disk. The stream completes without emitting any chunks despite having a valid size (result.size.totalBytes returns the correct value). The file ends up being 0kb.
I verified the issue is not related to writing to disk — writing hardcoded bytes to a file works correctly.
Here's the relevant code:
interact_api.dartcore_utils.dartStacktrace / error logs.
Package (youtube_explode_dart) version
3.0.5
Checklist
Additional notes
No response