我的任务是从服务器下载部分HLS流并在Android应用程序中本地播放。
我已经下载了必需的.ts
块并形成了播放列表:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:10.000000,
/storage/emulated/0/Android/data/com.example.myapp/files/savedMovies/chunk0.ts
#EXTINF:10.000000,
/storage/emulated/0/Android/data/com.example.myapp/files/savedMovies/chunk1.ts
#EXTINF:10.000000,
/storage/emulated/0/Android/data/com.example.myapp/files/savedMovies/chunk2.ts
#EXTINF:10.000000,
/storage/emulated/0/Android/data/com.example.myapp/files/savedMovies/chunk3.ts
#EXT-X-ENDLIST
接下来,我已将指向播放列表的链接传递给android.media.MediaPlayer
实例:
String fileLink = "/storage/emulated/0/Android/data/com.example.myapp/files/savedMovies/savedPlaylist.ts";
mediaPlayer.setDataSource(fileLink);
结果我收到了这样的例外:
W/System.err: java.io.IOException: Prepare failed.: status=0x1
W/System.err: at android.media.MediaPlayer._prepare(Native Method)
W/System.err: at android.media.MediaPlayer.prepare(MediaPlayer.java:1408)
W/System.err: at com.example.myapp.MainActivity.surfaceCreated(MainActivity.java:305)
W/System.err: at android.view.SurfaceView.updateWindow(SurfaceView.java:656)
W/System.err: at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:172)
W/System.err: at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1013)
W/System.err: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2542)
W/System.err: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1537)
W/System.err: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183)
W/System.err: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)
W/System.err: at android.view.Choreographer.doCallbacks(Choreographer.java:734)
W/System.err: at android.view.Choreographer.doFrame(Choreographer.java:670)
W/System.err: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)
W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6776)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
如果我传递到播放器文件的路径并且原始服务器的播放列表保存在本地(使用http链接到块),则会发生同样的事情
我试图在VLC播放器中播放本地文件:
intent.setDataAndType(Uri.parse(fileUrl), "video/m3u8");
但也会导致错误(包括本地链接和http链接)
任何人都可以帮助我吗?
我已经检查了权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
我的代码:
private void playVideo(String fileUrl) {
surfaceView.setVisibility(View.VISIBLE);
this.fileUrl = fileUrl;
holder = surfaceView.getHolder();
holder.addCallback(this);
}
@Override
public void onPrepared(MediaPlayer player) {
mediaPlayer.start();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mediaPlayer = new MediaPlayer();
File file = new File(fileUrl);
FileInputStream inputStream = new FileInputStream(file);
mediaPlayer.reset();
mediaPlayer.setDataSource(inputStream.getFD());
inputStream.close();
mediaPlayer.setDisplay(holder);
mediaPlayer.prepare();
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnVideoSizeChangedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onPrepared(MediaPlayer player) {
mediaPlayer.start();
}