2

I have a requirement where I need to extract metadata from an HLS Stream in Android. I have found two libraries FFMPEG and VITAMIO. Considering the fragmented support of HLS streaming on android, and after reading a plethora of even more confusing articles, I have finalized the above two libraries for further research.I have not found a single application where the extraction of metadata(timed metadata) has been done on Android.

I am confused if it is even possible on Android. And if so,which approach should I use... help me out guys....

anz
  • 1,317
  • 2
  • 13
  • 25

2 Answers2

7

Parsing m3u8 is relatively easy. You need to create HashMap of String and Integer to store parsed data. M3U8 file is composed of 3 entry tags which represent the entry of the m3u8, media sequence and the segment duration of all media files, except the last one, which differs from the rest.

After each #EXTINF integer duration is sticked to it, so we need to get this by parsing the string with basic regex.

private HashMap<String, Integer> parseHLSMetadata(InputStream i ){

        try {
            BufferedReader r = new BufferedReader(new InputStreamReader(i, "UTF-8"));
            String line;
            HashMap<String, Integer> segmentsMap = null;
            String digitRegex = "\\d+";
            Pattern p = Pattern.compile(digitRegex);

            while((line = r.readLine())!=null){
                if(line.equals("#EXTM3U")){ //start of m3u8
                    segmentsMap = new HashMap<String, Integer>();
                }else if(line.contains("#EXTINF")){ //once found EXTINFO use runner to get the next line which contains the media file, parse duration of the segment
                    Matcher matcher = p.matcher(line);
                    matcher.find(); //find the first matching digit, which represents the duration of the segment, dont call .find() again that will throw digit which may be contained in the description.
                    segmentsMap.put(r.readLine(), Integer.parseInt(matcher.group(0)));
                }
            }
            r.close();
            return segmentsMap;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

Cheers.

Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
  • Thanks for the reply ...I need to read the metadata...for eg I need to know when the user is playing, pausing,seeking a particular time in the video etc..Will this data be stored(updated in the m3u8 file). ALso android default video player does not allow for seeking in an hls stream..Should I build my own video stack using ffmpeg or go for vitamio?? – anz Oct 21 '13 at 06:02
  • Updating m3u8 is totally another thing than reading metadata. – Nikola Despotoski Oct 21 '13 at 14:31
  • that function give me only even index .ts file can you tell me how can i get all .ts files from m3u8 link android – humayoon siddique Mar 04 '16 at 13:09
2

The timed text metadata isn't stored in the m3u8 file as suggested by Nikola's answer, but instead stored in the mpeg2 ts segments. An overview of how it's embedded in the ts is available here: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/HTTP_Live_Streaming_Metadata_Spec/HTTP_Live_Streaming_Metadata_Spec.pdf

You can try extracting the metadata with ffmpeg, the command should be something along the lines of this:

ffmpeg -i in.ts -f ffmetadata metadata.txt

You'll need to do the equivalent using jni and libavformat. It's not incredibly easy, and you'll still need to come up with a mechanism for signaling the read metadata to your application.

If you can, I would recommend signaling the timed metadata via a separate mechanism. Could you extract it and put it as a text file that your player downloads separately? Then you lines up with the timeline as reported by the video player? That would be much simpler to implement, but I don't know your requirements.

vipw
  • 7,593
  • 4
  • 25
  • 48
  • Thanks for the reply...do you know if my requrement can be met using libvlc for android – anz Oct 24 '13 at 09:28
  • 1
    libvlc_media_new_location() + libvlc_media_parse() + libvlc_media_get_meta() looks like it might work. I've never tried it myself. – vipw Oct 24 '13 at 10:29
  • Can you provide me with any pointers on how to retrieve the metadata from the ts segments? – anz Nov 13 '13 at 07:51