使用正则表达式解析HLS m3u8文件

时间:2013-03-07 07:54:54

标签: android regex http-live-streaming m3u8

我想解析HLS master m3u8文件,并从中获取带宽,分辨率和文件名。目前我正在使用String解析来搜索某些模式的字符串,并使用子字符串来获取值。

示例文件:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234
Stream1/index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=763319,RESOLUTION=480x270
Stream2/index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1050224,RESOLUTION=640x360
Stream3/index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1910937,RESOLUTION=640x360
Stream4/index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3775816,RESOLUTION=1280x720
Stream5/index.m3u8

但是我发现我们可以使用这个问题中提到的正则表达式来解析它: Problem matching regex pattern in Android

我没有任何正则表达的想法,所以有人请指导我使用正则表达式解析它。

或者有人可以帮我写regexp来解析下面字符串中的BANDWIDTH和RESOLUTION值

#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234

3 个答案:

答案 0 :(得分:10)

您可以尝试这样的事情:

    final Pattern pattern = Pattern.compile("^#EXT-X-STREAM-INF:.*BANDWIDTH=(\\d+).*RESOLUTION=([\\dx]+).*");

    Matcher matcher = pattern.matcher("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234");
    String bandwidth = "";
    String resolution = "";

    if (matcher.find()) {
        bandwidth = matcher.group(1);
        resolution = matcher.group(2);
    }

将带宽和分辨率设置为正确的(字符串)值。

我没有在Android设备或模拟器上试过这个,但是根据你发送的链接和android API判断它应该和上面普通的旧java一样。

正则表达式匹配以#EXT-X-STREAM-INF:开头的字符串,其中包含BANDWIDTHRESOLUTION,后跟正确的值格式。然后在后引用组1和2中对它们进行反向引用,以便我们可以提取它们。

修改

如果并非总是存在RESOLUTION,那么您可以将该部分设为可选的:

"^#EXT-X-STREAM-INF:.*BANDWIDTH=(\\d+).*(?:RESOLUTION=([\\dx]+))?.*"

如果只有resolutionnull字符串将为BANDWIDTH

<强> EDIT2:

?使事情变得可选,而(?:___)表示被动组(而不是后引用组(___)。所以它基本上是一个可选的被动组。所以,是的,里面的任何东西它将是可选的。

.与单个字符匹配,而*表示将重复零次或多次。因此.*将匹配零个或多个字符。我们需要这个的原因是在我们匹配的东西之间消耗任何东西,例如#EXT-X-STREAM-INF:BANDWIDTH之间的任何内容。有很多方法可以做到这一点,但.*是最通用的/广泛的。

\d基本上是一组表示数字(0-9)的字符,但由于我们将字符串定义为Java字符串,因此我们需要双\\,否则需要Java编译器将失败,因为它无法识别转义字符\d(在Java中)。相反,它会将\\解析为\,以便我们在传递给\d构造函数的最终字符串中获得Pattern

[\dx]+表示字符+0-9中的一个或多个字符(x)。 [\dx\d]将是同一组字符中的单个字符(无+)。

如果您对正则表达式感兴趣,可以查看regular-expressions.info或/和regexone.com,在那里您可以找到更多深入解答所有问题的答案。

答案 1 :(得分:0)

我发现这个可能会有所帮助 http://sourceforge.net/projects/m3u8parser/
(许可证:LGPLv3)

答案 2 :(得分:0)

你可以只拆分字符串,这就是我在 python 中的意思。

fu ="#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=476416,RESOLUTION=416x234"

for chunk in fu.split(':')[1].split(','):
    if chunk.startswith('BANDWIDTH'):
        bandwidth = int(chunk.split('=')[1])
    if chunk.startswith('RESOLUTION'):
        resolution = chunk.split('=')[1]