使用 VideoView 时出现 java.io.FileNotFoundException

Posted

技术标签:

【中文标题】使用 VideoView 时出现 java.io.FileNotFoundException【英文标题】:Getting java.io.FileNotFoundException when using VideoView 【发布时间】:2016-10-01 21:12:45 【问题描述】:

我有以下代码:

   VideoView videoView = (VideoView)findViewById(R.id.instructionsvideo);
   assert videoView != null;
   videoView.setVideoPath("android.resource://" + getPackageName() + R.raw.testnatureclip);
   videoView.start();

“testnatureclip”位于原始文件夹中:

由于某种原因,在我构建项目后,文件变为红色。

这是我得到的错误: com.roymunson.vroy.copypastakeyboard W/MediaPlayer: Couldn't open file on client side; trying server side: java.io.FileNotFoundException: No package found for authority: android.resource://com.roymunson.vroy.copypastakeyboard2131165184

mp4应该是H.264格式编码的,不知道我用的在线编码服务有没有用。

此外,视频视图与文件的尺寸不同,如果这很重要的话。

有什么问题?文件路径是否不正确,或者我在初始化视频视图时缺少一些元素?

更新一:

使用 User8 的解决方案出现以下错误:

roymunson.vroy.copypastakeyboard W/MediaPlayer: Couldn't open file on client side; trying server side: java.io.FileNotFoundException: No content provider: /2131165184
10-01 17:36:20.912 28156-28156/com.roymunson.vroy.copypastakeyboard W/VideoView: Unable to open content: /2131165184
                                                                                 java.io.IOException: setDataSource failed.
                                                                                     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1100)
                                                                                     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1074)
                                                                                     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1028)
                                                                                     at android.widget.VideoView.openVideo(VideoView.java:346)
                                                                                     at android.widget.VideoView.-wrap0(VideoView.java)
                                                                                     at android.widget.VideoView$7.surfaceCreated(VideoView.java:623)
                                                                                     at android.view.SurfaceView.updateWindow(SurfaceView.java:582)
                                                                                     at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177)
                                                                                     at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
                                                                                     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2067)
                                                                                     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
                                                                                     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)
                                                                                     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
                                                                                     at android.view.Choreographer.doCallbacks(Choreographer.java:670)
                                                                                     at android.view.Choreographer.doFrame(Choreographer.java:606)
                                                                                     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
                                                                                     at android.os.Handler.handleCallback(Handler.java:746)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                     at android.os.Looper.loop(Looper.java:148)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:5443)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

【问题讨论】:

【参考方案1】:

我找到了 2 个解决方案:

String uriPath = "android.resource://" + getPackageName() + "/raw/testnatureclip";
Uri uri = Uri.parse(uriPath);
videoView.setVideoURI(uri);

videoView.setVideoURI(Uri.parse("android.resource://ABSOLUTE_PACKAGE_NAME/" + R.raw.testnatureclip));

【讨论】:

您发布时我正在编辑我的答案。 +1 是的,只需使用 Uri 方法。关于getPackageResourcePath(),试试String uriPath = getPackageResourcePath() + "/raw/testnatureclip"; 来缩短代码。 当您有多模块项目时,此代码不起作用。看这里:***.com/a/8616187/8187578【参考方案2】:

试试这个,指定一个绝对包名路径并使用 Uri:

 videoView.setVideoURI(Uri.parse("android.resource://com.roymunson.vroy.copypastakeyboard/" 
                                  + R.raw.testnatureclip));

另外,你为什么不直接使用getPackageResourcePath()来访问资源呢?

那么,您通常无法通过这种方式访问​​它们,您应该仅使用他们的resourceID,这里是关于该主题的讨论:Access resource files in Android。

【讨论】:

我看了你链接的帖子,但我不明白如何直接使用getPackageResourcePath() 另外,我尝试了您的解决方案,但没有成功,我将在原始帖子的编辑中发布堆栈跟踪。【参考方案3】:

尝试从原始文件夹获取路径:

    String path = "android.resource://" + getPackageName() + "/" + R.raw.testnatureclip;

我建议使用ExoPlayer 而不是VideoView

应用分级:

implementation 'com.google.android.exoplayer:exoplayer:2.10.8'

布局xml:

<com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/video_view"
        android:layout_
        android:layout_
        android:layout_centerInParent="true" />

java代码:

PlayerView videoView = findViewById(R.id.video_view);
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this);
videoView.setPlayer(player);
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "yourApplicationName"));
// This is the MediaSource representing the media to be played.
MediaSource videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(path));
// Prepare the player with the source.
player.prepare(videoSource);
player.setPlayWhenReady(true); 

【讨论】:

以上是关于使用 VideoView 时出现 java.io.FileNotFoundException的主要内容,如果未能解决你的问题,请参考以下文章

在 videoView 中播放视频时出现 java.lang.StringIndexOutOfBoundsException:Android v 4.2.1

使用 java.io.File.createTempFile 时出现 Veracode 不安全临时文件错误

使用 YARN 在集群模式下运行 spark 时出现 java.io.FileNotFoundException

在android HttpURLConnection中打开输入流时出现java.io.FileNotFoundException

在内部存储中打开视频

Proguard 错误:“处理任务 java.io.IOException 时出现异常:请先更正上述警告”