Khaled
Khaled

Reputation: 425

exoplayer2 is not playing local video from SD card (java.io.FileNotFoundException)

I am trying to play a hardcoded video from SD card (not URL). I checked the file exists in the app folder into SD card but I am unable to play it. After searching in some threads at stackoverflow (Playing mp4 from cacheDir), I could not play the video from the SD card. Here is my code:

public void initVideoPlayer(String path) {
    AppCompatActivity activity = (AppCompatActivity) getActivity();
    dialog.setContentView(R.layout.wifi_video_popup);
    playerView = dialog.findViewById(R.id.player);
    fullscreenButton = playerView.findViewById(R.id.exo_fullscreen_icon);

    fullscreenButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
          //...
        }
    });

    playerView.setPlayer(player);
    playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT);

    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(activity.getApplicationContext(), context.getString(R.string.app_name)));

    File file = new File(context.getApplicationContext().getExternalFilesDir(null), "file_1.mp4");
    Uri uri = Uri.fromFile(file);
    DataSpec dataSpec = new DataSpec(uri);

    final FileDataSource fileDataSource = new FileDataSource();
    try {
        fileDataSource.open(dataSpec);
    } catch (FileDataSource.FileDataSourceException e) {
        e.printStackTrace();
    }

    DataSource.Factory factory = new DataSource.Factory() {
        @Override
        public DataSource createDataSource() {
            return fileDataSource;
        }
    };

    MediaSource videoSource = new ProgressiveMediaSource.Factory(factory)
            .createMediaSource(fileDataSource.getUri());

    player.prepare(videoSource);
    player.setPlayWhenReady(true);
    dialog.show();
}

So, any indicator where things go wrong in my code?

========= Update =========

After carefully debugging the code, I noticed runtime error: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.xxx.yyy/files/file_1.mp4: open failed: ENOENT (No such file or directory)

But the fact is that the file is there already. I also checked SD card in my macbook, and I noticed the file is located at: /Volumes/NO NAME/Android/data/com.xxx.yyy/files/file_1.mp4 so why android is unable to find the file?

Finally, this is the access permission I have in my AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

Upvotes: 0

Views: 1228

Answers (1)

Ahmed Nashwan
Ahmed Nashwan

Reputation: 11

If your device has Android 11 or more, you need to give the app permission to access and control all files in storage.

Of course you can navigate the user to allow this in storage permission using below code.

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    if (!Environment.isExternalStorageManager()) {
                        val intent =
                            Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
                        val uri: Uri = Uri.fromParts("package", packageName, null)
                        intent.data = uri
                        startActivity(intent)

                    }
                }

Upvotes: 1

Related Questions