4

我想解析 HLS 主 m3u8 文件并从中获取带宽、分辨率和文件名。目前我正在使用字符串解析来搜索字符串以查找某些模式并执行子字符串以获取值。

示例文件:

#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

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

或者有人可以帮助我编写正则表达式以从下面的字符串中解析出 BANDWIDTH 和 RESOLUTION 值

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

4 回答 4

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]+))?.*"

resolution字符串将出现null在 only 的情况下BANDWIDTH

编辑2:

?使事情成为可选的,并且(?:___)意味着一个被动组(与反向引用组相反(___)。所以它基本上是一个可选的被动组。所以是的,它里面的任何东西都是可选的。

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

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

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

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

于 2013-03-07T08:29:30.203 回答
1

你可以只拆分字符串,这就是我在 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]
于 2021-03-26T18:47:07.580 回答
0

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

于 2015-12-28T08:26:02.123 回答
0

您还可以使用:Python m3u8 解析器。

下面的例子:

import m3u8

playlist = """
#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
"""
_playlist = m3u8.loads(playlist).playlists

for item in _playlist:
    item_uri   = item.uri 
    resolution = item.stream_info.resolution
    bandwidth  = item.stream_info.bandwidth
    print(item_uri ,resolution , bandwidth )

结果将是:

Stream1/index.m3u8 (416, 234) 476416
Stream2/index.m3u8 (480, 270) 763319
Stream3/index.m3u8 (640, 360) 1050224
Stream4/index.m3u8 (640, 360) 1910937
Stream5/index.m3u8 (1280, 720) 3775816
于 2022-02-02T13:34:07.163 回答