Why ExoPlayer in Android OS shows black preview screen while preview
Harshu2032000 opened this issue · comments
I'm developing an app that displays data uploaded by a user to a server (audio, image, or video). The image and audio are displayed correctly but for the video, it shows a black previw screen. also, I got some errors as below:
E/ExoPlayerImplInternal(18479): Playback error
E/ExoPlayerImplInternal(18479): com.google.android.exoplayer2.ExoPlaybackException: Source error
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:684)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:656)
E/ExoPlayerImplInternal(18479): at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal(18479): at android.os.Looper.loopOnce(Looper.java:201)
E/ExoPlayerImplInternal(18479): at android.os.Looper.loop(Looper.java:288)
E/ExoPlayerImplInternal(18479): at android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal(18479): Caused by: com.google.android.exoplayer2.upstream.FileDataSource$FileDataSourceException: java.io.FileNotFoundException: : open failed: ENOENT (No such file or directory)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.upstream.FileDataSource.openLocalFile(FileDataSource.java:211)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.upstream.FileDataSource.open(FileDataSource.java:122)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:269)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:90)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1013)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:420)
E/ExoPlayerImplInternal(18479): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
E/ExoPlayerImplInternal(18479): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
E/ExoPlayerImplInternal(18479): at java.lang.Thread.run(Thread.java:1012)
E/ExoPlayerImplInternal(18479): Caused by: java.io.FileNotFoundException: : open failed: ENOENT (No such file or directory)
E/ExoPlayerImplInternal(18479): at libcore.io.IoBridge.open(IoBridge.java:574)
E/ExoPlayerImplInternal(18479): at java.io.RandomAccessFile.(RandomAccessFile.java:289)
E/ExoPlayerImplInternal(18479): at java.io.RandomAccessFile.(RandomAccessFile.java:152)
E/ExoPlayerImplInternal(18479): at com.google.android.exoplayer2.upstream.FileDataSource.openLocalFile(FileDataSource.java:192)
E/ExoPlayerImplInternal(18479): ... 8 more
E/ExoPlayerImplInternal(18479): Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
E/ExoPlayerImplInternal(18479): at libcore.io.Linux.open(Native Method)
E/ExoPlayerImplInternal(18479): at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
E/ExoPlayerImplInternal(18479): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:274)
E/ExoPlayerImplInternal(18479): at libcore.io.ForwardingOs.open(ForwardingOs.java:563)
E/ExoPlayerImplInternal(18479): at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7919)
E/ExoPlayerImplInternal(18479): at libcore.io.IoBridge.open(IoBridge.java:560)
E/ExoPlayerImplInternal(18479): ... 11 more
I/flutter (18479): Zone error: PlatformException(VideoError, Video player had error com.google.android.exoplayer2.ExoPlaybackException: Source error, null, null)
I/flutter (18479):
how to resolve these errors and make the video display work
How are you specifying the URI of the local file? Seems like the error is originating in FileDataSource.openLocalFile
before any playback actually can begin.
Note that FileNotFoundException
can mean that your app doesn't have access to the file in question (i.e. it might exist if you look with adb shell ls
). More info about file access on Android, and the required permissions, is here: https://developer.android.com/training/data-storage
Hey @Harshu2032000. We need more information to resolve this issue but there hasn't been an update in 14 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.
If you have more information that will help us get to the bottom of this, just add a comment!
How are you specifying the URI of the local file? Seems like the error is originating in
FileDataSource.openLocalFile
before any playback actually can begin.
Widget _buildMediaWidget(String filePath) {
final file = File(filePath);
final fileExtension = filePath.split('.').last.toLowerCase();
if (fileExtension == 'jpg' ||
fileExtension == 'jpeg' ||
fileExtension == 'png') {
return Image.file(file);
} else if (fileExtension == 'mp3') {
return AudioPlayerWidget(file: file);
} else if (fileExtension == 'mp4') {
videoPlayerController = VideoPlayerController.file(file);
videoPlayerController.initialize().then((_) {
// Ensure the video is actually loaded before playing it.
if (videoPlayerController.value.isInitialized) {
videoPlayerController.play();
}
});
final chewieController = ChewieController(
videoPlayerController: videoPlayerController,
autoPlay: true,
looping: true,
// Customize other ChewieController properties here
);
return Chewie(controller: chewieController);
} else if (fileExtension == 'webm') {
videoPlayerController = VideoPlayerController.file(file);
videoPlayerController.initialize().then((_) {
// Ensure the video is actually loaded before playing it.
if (videoPlayerController.value.isInitialized) {
videoPlayerController.play();
}
});
final chewieController = ChewieController(
videoPlayerController: videoPlayerController,
autoPlay: true,
looping: true,
// Customize other ChewieController properties here
);
return Chewie(controller: chewieController);
} else {
return const Text('Invalid file type');
}
}
@OverRide
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<Map<String, dynamic>>>(
future: _fetchDeepfakes(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (snapshot.hasData) {
deepfakes = snapshot.data!;
return ListView.builder(
itemCount: deepfakes.length,
itemBuilder: (context, index) {
final deepfake = deepfakes[index];
final String filePath = deepfake['file'];
print(filePath);
final Widget mediaWidget = _buildMediaWidget(filePath);
return ListTile(
title: Column(
children: [
Text(
'Result: ${deepfake['result']}',
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
'Confidence: ${deepfake['confidence']}',
style: const TextStyle(fontWeight: FontWeight.bold),
),
Container(
child: mediaWidget,
),
],
),
subtitle: Text('Description: ${deepfake['description']}'),
);
},
);
} else {
return const Center(child: Text('No data available'));
}
},
),
);
}
}
in this way
How are you specifying the URI of the local file? Seems like the error is originating in
FileDataSource.openLocalFile
before any playback actually can begin.
I have added all the permissions in my manifest file.
I have added all the permissions in my manifest file.
None of the code you have posted shows you requesting runtime storage permissions, which is required for 'dangerous' permissions such as READ_MEDIA_VIDEO
:
- https://developer.android.com/training/permissions/requesting
- https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_VIDEO
Our demo app requests these runtime permissions here:
media/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java
Lines 357 to 360 in d833d59
I have added all the permissions in my manifest file.
None of the code you have posted shows you requesting runtime storage permissions, which is required for 'dangerous' permissions such as
READ_MEDIA_VIDEO
:
- https://developer.android.com/training/permissions/requesting
- https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_VIDEO
Our demo app requests these runtime permissions here:
media/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java
Lines 357 to 360 in d833d59
this is how I have declared permissions
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
@Harshu2032000
By declaring the permission in the manifest, you succeeded at step 1 in the following workflow: https://developer.android.com/training/permissions/requesting#workflow_for_requesting_permissions
There are many additional steps, one of them being a runtime permission request - which is why we linked you to the Util method we use in our demo app.
I think at this stage, you have all the required information to help you recover from your black screen and sort out the media access exception. I'm going to close the issue.