Android 从HLS流(m3u8文件)提取元数据

Android 从HLS流(m3u8文件)提取元数据,android,ffmpeg,http-live-streaming,m3u8,vitamio,Android,Ffmpeg,Http Live Streaming,M3u8,Vitamio,我需要从Android中的HLS流中提取元数据。我找到了两个图书馆FFMPEG和VITAMIO。考虑到android上对HLS流媒体的零碎支持,在阅读了大量甚至更令人困惑的文章后,我最终确定了上述两个库以供进一步研究。我还没有发现任何一个应用程序可以在android上提取元数据(定时元数据) 我很困惑,在安卓系统上是否可能实现这一点。如果是这样,我应该使用哪种方法。。。 帮帮我,伙计们……解析m3u8相对容易。您需要创建String的HashMap和Integer来存储解析数据。M3U8文件由3

我需要从Android中的HLS流中提取元数据。我找到了两个图书馆FFMPEG和VITAMIO。考虑到android上对HLS流媒体的零碎支持,在阅读了大量甚至更令人困惑的文章后,我最终确定了上述两个库以供进一步研究。我还没有发现任何一个应用程序可以在android上提取元数据(定时元数据)

我很困惑,在安卓系统上是否可能实现这一点。如果是这样,我应该使用哪种方法。。。
帮帮我,伙计们……

解析m3u8相对容易。您需要创建
String
HashMap
Integer
来存储解析数据。M3U8文件由3个条目标签组成,代表M3U8的条目、媒体序列和所有媒体文件的段持续时间,但最后一个不同于其他文件

在每个
#exef
整数持续时间都被粘贴到它之后,因此我们需要通过使用基本正则表达式解析字符串来获得它

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;
    }
private HashMap parseHLSMetadata(InputStream i){
试一试{
BufferedReader r=新的BufferedReader(新的InputStreamReader(i,“UTF-8”));
弦线;
HashMap segmentsMap=null;
字符串digitRegex=“\\d+”;
Pattern p=Pattern.compile(digitRegex);
而((line=r.readLine())!=null){
if(line.equals(“#EXTM3U”){//m3u8的开始
segmentsMap=新HashMap();
}否则,如果(line.contains(“#exef”){//一旦找到exefo,请使用runner获取包含媒体文件的下一行,分析该段的持续时间
匹配器匹配器=p.Matcher(线);
matcher.find();//找到第一个匹配的数字,它表示段的持续时间,不要再次调用.find(),它将抛出描述中可能包含的数字。
segmentsMap.put(r.readLine(),Integer.parseInt(matcher.group(0));
}
}
r、 close();
返回段SMAP;
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回null;
}

干杯。

按照尼古拉的回答,定时文本元数据不存储在m3u8文件中,而是存储在mpeg2 ts段中。有关如何将其嵌入ts的概述,请参见:

您可以尝试使用ffmpeg提取元数据,该命令应符合以下内容:

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

您需要使用jni和libavformat进行等效操作。这并不容易,而且您仍然需要提出一种机制,将读取的元数据发送到应用程序


如果可以的话,我建议通过单独的机制发送定时元数据。你能把它解压缩成一个文本文件,让你的播放器单独下载吗?然后按照视频播放器报告的时间线排列?这将更容易实现,但我不知道您的要求。

谢谢您的回复…我需要阅读元数据…例如,我需要知道用户何时播放、暂停、在视频中寻找特定时间等。这些数据是否会被存储(在m3u8文件中更新)。另外,android默认视频播放器不允许在hls流中搜索。我应该使用ffmpeg构建自己的视频堆栈还是使用vitamio?更新m3u8完全是另一回事,而不是读取元数据。该功能只提供索引.ts文件。您能告诉我如何从m3u8链接获取所有.ts文件吗?谢谢您的回复…您能告诉我吗知道使用libvlc for androidlibvlc_media_new_location()+libvlc_media_parse()+libvlc_media_get_meta()是否可以满足我的要求看起来可能会奏效。我自己从来没有试过。你能给我一些关于如何从ts段检索元数据的建议吗?