androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

Our demo app requests these runtime permissions here:

if (Util.maybeRequestReadStoragePermission(/* activity= */ this, mediaItem)) {
// The player will be reinitialized if the permission is granted.
return Collections.emptyList();
}

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:

Our demo app requests these runtime permissions here:

if (Util.maybeRequestReadStoragePermission(/* activity= */ this, mediaItem)) {
// The player will be reinitialized if the permission is granted.
return Collections.emptyList();
}

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.