My task is to download some part of HLS stream from server and play it locally in android app.
I've download required .ts
chunks and formed playlist:
#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
Next, I've passed the link to playlist to android.media.MediaPlayer
instance:
String fileLink = "/storage/emulated/0/Android/data/com.example.myapp/files/savedMovies/savedPlaylist.ts";
mediaPlayer.setDataSource(fileLink);
As result I've received such exception:
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)
The same thing is happening if I pass to player file's path with original server's playlist saved locally (with http links to chunks)
I've tried to play local file in VLC player:
intent.setDataAndType(Uri.parse(fileUrl), "video/m3u8");
But causes an error too (both with local and http links)
Can anyone help me with this?
I've already checked permissions:
<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" />
My code:
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();
}
As I understand MediaPlayer is unable to play local m3u8
files.
I used ExoPlayer instead, works well now