media icon indicating copy to clipboard operation
media copied to clipboard

Why ExoPlayer in Android OS shows black preview screen while preview

Open Harshu2032000 opened this issue 1 year ago • 2 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

Harshu2032000 avatar Jun 07 '24 09:06 Harshu2032000

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.

oceanjules avatar Jun 07 '24 10:06 oceanjules

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

icbaker avatar Jun 07 '24 10:06 icbaker

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!

google-oss-bot avatar Jul 09 '24 01:07 google-oss-bot

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

Harshu2032000 avatar Jul 15 '24 06:07 Harshu2032000

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.

Harshu2032000 avatar Jul 15 '24 06:07 Harshu2032000

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: https://github.com/androidx/media/blob/d833d59124d795afc146322fe488b2c0d4b9af6a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java#L357-L360

icbaker avatar Jul 15 '24 09:07 icbaker

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:

https://github.com/androidx/media/blob/d833d59124d795afc146322fe488b2c0d4b9af6a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java#L357-L360

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 avatar Jul 15 '24 09:07 Harshu2032000

@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.

oceanjules avatar Jul 15 '24 11:07 oceanjules