Playing .m3u8 file through HTTPS on android 2.3

2019-02-14 19:27发布

问题:

At some point in my code, the app finds an URL that points to a .m3u8 file. This is what happens next :

mVideoView.setVideoURI(Uri.parse(feed.getUrl().toString())); // feed.getUrl returns the url
mVideoView.start();

And it works FINE on Android 3.1+. Not on earlier versions because it uses https (see this : http://developer.android.com/guide/appendix/media-formats.html )

So what I did is I created a new version of my app for Android 2.2+ that uses vitamio , a library that's supposed to make it easier for me. However, where (android.widget.VideoView) handled it perfectly, (io.vov.vitamio.widget.VideoView) takes a very long time to load the stream and ends up saying this while crashing :

BUT, when I try to load this URL : http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8 It works fine !

I can't share the URL I need to use, but here's the contents of the .m3u8 it is pointing to:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=264000
playlist.m3u8?session=003016302664236&index=0
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1364000
playlist.m3u8?session=003016302664236&index=1
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=44000
playlist.m3u8?session=003016302664236&index=2

So the main differences I can see between this one and the Apple sample one, is I'm using https, my file is pointing to other .m3u8 files (while Apple's .m3u8 is pointing to .ts files).. Both seem to use AAC audio.

The problem seems to be related to vitamio. How can I get around this crash ? Thank you very much.

回答1:

I found a solution !

So the first thing I should say is that I was confused, and I wasn't using HTTPS, but my solution should work for https too.

First, you probably need to use Vitamio like I did, because Gingerbread does not support live streaming (again, read this). Now the thing is that if your M3u8 file is a list of .ts files, it should work fine. But if it's pointing to other m3u8 files..

Well you're gonna have to parse it yourself. You can do it this way for example :

url = new URL(livetvchannel.getUrl());
InputStream M3U8 = (InputStream) url.getContent();      
BufferedReader br = new BufferedReader(new InputStreamReader(M3U8));
for(int i = 0; i < 2; ++i)
    br.readLine();
String target = br.readLine(); //this parses the third line of the playlist
br.close();
url = new URL(baseURL.concat(target)); 
//if the m3u8 url is relative, you have to concat it with the path
//Note: You have to do all this in a thread, you can't do network on UiThread


mVideoView.setVideoURI(Uri.parse(url.toString())); //Run this on UiThread

url will point to the video stream. And there you go ! Wasn't that hard in the end. :)