【问题标题】:Php Curl parsing a m3u file [duplicate]Php Curl解析m3u文件[重复]
【发布时间】:2018-11-27 06:07:52
【问题描述】:

希望你们能帮帮我。我有以下 .m3u 文件

#EXTM3U
#EXTINF:-1 tvg-id="" tvg-name="A&E" tvg-logo="" group-title="ENTRETENIMIENTO",A&E
http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
#EXTINF:-1 tvg-id="" tvg-name="ABC Puerto Rico" tvg-logo="" group-title="NACIONALES",ABC Puerto Rico
http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/96.ts
#EXTINF:-1 tvg-id="" tvg-name="Animal Planet" tvg-logo="" group-title="ENTRETENIMIENTO",Animal Planet
http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/185.ts

如你所见,文件有主标签 #EXTM3U 及以下开始视频信息标签 (#EXTINF:-1 ...) 及以下视频链接条目 (http:// . ....)

您能否明确告诉我如何解析整个文件(这是一个非常大的文件)并将字段保存在数组中,例如像这样? 视频[ ] 后来我可以访问每个视频属性让我们说 videos[0]['title'] 来获取第一个视频的标题?依此类推,使用其他属性,例如 videos[42]['link'] 并获取视频 #42 的链接。

我已经在使用 curl 将文件内容放入这样的变量中

<?php
   $handler = curl_init("link to m3u file");  
   $response = curl_exec ($handler);  
   curl_close($handler); 
   echo $response;
?>

我现在需要的是解析 Curl 响应并将所有视频信息保存到一个数组中,我可以在其中访问每个视频的每个属性。

我知道我必须使用一些正则表达式或类似的东西。我只是不明白怎么做。你能帮我一些代码吗?非常感谢。

【问题讨论】:

  • 这些空格是什么,是制表符还是空格?如果它们是标签,您可以使用 csv 解析它们,例如 fgetcsv ($handle, 0, "\t") 可能使用 fopen('php://temp') 作为 steamwrapper。
  • 空格不是制表符。

标签: php curl video


【解决方案1】:

看看 Regx 的魔力

$string = <<<CUT
#EXTM3U
#EXTINF:-1 tvg-id="" tvg-name="A&E" tvg-logo="" group-title="ENTRETENIMIENTO",A&E`http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
#EXTINF:-1 tvg-id="" tvg-name="ABC Puerto Rico" tvg-logo="" group-title="NACIONALES",ABC Puerto Rico
http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/96.ts
CUT;

preg_match_all('/(?P<tag>#EXTINF:-1)|(?:(?P<prop_key>[-a-z]+)=\"(?P<prop_val>[^"]+)")|(?<something>,[^\r\n]+)|(?<url>http[^\s]+)/', $string, $match );

$count = count( $match[0] );

$result = [];
$index = -1;

for( $i =0; $i < $count; $i++ ){
    $item = $match[0][$i];

    if( !empty($match['tag'][$i])){
        //is a tag increment the result index
        ++$index;
    }elseif( !empty($match['prop_key'][$i])){
        //is a prop - split item
        $result[$index][$match['prop_key'][$i]] = $match['prop_val'][$i];
    }elseif( !empty($match['something'][$i])){
        //is a prop - split item
        $result[$index]['something'] = $item;
    }elseif( !empty($match['url'][$i])){
        $result[$index]['url'] = $item ;
    }
}

print_r( $result );

退货

array (
  0 => 
  array (
    'tvg-name' => 'A&E',
    'group-title' => 'ENTRETENIMIENTO',
    'something' => ',A&E`http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts',
    'url' => 'http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts',
  ),
  1 => 
  array (
    'tvg-name' => 'ABC Puerto Rico',
    'group-title' => 'NACIONALES',
    'something' => ',ABC Puerto Rico',
    'url' => 'http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/96.ts',
  ),
)

说真的,尽管我不知道其中一些是什么something。无论如何应该让你开始。

对于正则表达式,分解后实际上非常简单。真正的诀窍是使用preg_match_all 而不是preg_match

这是我们的正则表达式

 /(?P<tag>#EXTINF:-1)|(?:(?P<prop_key>[-a-z]+)=\"(?P<prop_val>[^"]+)")|(?<something>,[^\r\n]+)|(?<url>http[^\s]+)/

首先,我们将把它分解成更易于管理的部分。这些由管道| 分隔,用于或。每一个都可以被认为是一个单独的模式,匹配这个或下一个。现在,顺序可能很重要,因为它们将从左到右匹配,所以如果一个匹配在左边,它就会停止。所以你必须小心不要有一个可以在两个地方匹配的正则表达式(如果你不想要那个)。但是,它也可以为您所用,如下所示。这确实是我们正在处理的问题

 (?P<tag>#EXTINF:-1)

 (?:(?P<prop_key>[-a-z]+)=\"(?P<prop_val>[^"]+)")

 (?<something>,[^\r\n]+)

 (?<url>http[^\s]+)

四个正则表达式。对于所有这些(?P&lt;name&gt;...) 是一个命名的捕获组,它只是使它更具可读性,更容易找到位。如果您查看我用来查找匹配项的条件,例如!empty($match['tag'][$i]),我们可以使用tag 索引/键,因为有一个命名的捕获组,否则它将是1。将许多 regx 放在一起,如果您认为这实际上是嵌套的,那么 1 2 3 可能会变得混乱,因此标签等将是 $match[1][$i] 。无论如何,一旦取出,我们就有了

  • #EXTINF:-1 从字面上匹配这个字符串
  • (?:(?P&lt;prop_key&gt;[-a-z]+)=\"(?P&lt;prop_val&gt;[^"]+)") 这更复杂 (?: .. ) 是一个非捕获组,这是所以键/值在匹配数组中以相同的索引结束,但没有一起捕获,分解这是 ([-a-z]+)=\"([^"]+)\" 或匹配一个单词然后是=,然后是",而不是",以"结尾。基本上一侧捕获键,另一侧捕获不包括双引号的值
  • ,[^\r\n]+ 以逗号开头,然后是回车符
  • 最后一个http[^\s]一个网址

现在请记住我说过的关于顺序很重要的内容,这个 url http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts 将匹配最后一个表达式,除了它以 ,A&amp;Ehttp://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts` 开头,它匹配第三个,所以它永远不会到达数字 4

希望对您有所帮助,前提是您必须对 Regx 有一个基本的了解,这并不是一个完整教程的地方,您可以在几分钟内找到更好的示例,然后我可以提供。

为了完整起见,这里是preg_match_all 返回的部分内容

(
    [0] => Array(
            [0] => #EXTINF:-1
            [1] => tvg-name="A&E"
            [2] => group-title="ENTRETENIMIENTO"
            [3] => ,A&E`http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
            [4] => http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
            [5] => #EXTINF:-1
            [6] => tvg-name="ABC Puerto Rico"
            [7] => group-title="NACIONALES"
            [8] => ,ABC Puerto Rico
            [9] => http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/96.ts
        )
    [tag] => Array(
            [0] => #EXTINF:-1
            [1] => 
            [2] => 
            [3] => 
            [4] => 
            [5] => #EXTINF:-1
            [6] => 
            [7] => 
            [8] => 
            [9] => 
        )
    [1] => Array(
            [0] => #EXTINF:-1
            [1] => 
            [2] => 
            [3] => 
            [4] => 
            [5] => #EXTINF:-1
            [6] => 
            [7] => 
            [8] => 
            [9] => 
        )
    [prop_key] => Array(
            [0] => 
            [1] => tvg-name
            [2] => group-title
            [3] => 
            [4] => 
            [5] => 
            [6] => tvg-name
            [7] => group-title
            [8] => 
            [9] => 
        )
    [2] => Array( ... duplicate of prop_key .. ) 
   etc. 
)

在上面的数组中找到item的方法是,如果你在第一次运行索引0时查看for循环,匹配的主要部分$match[0][$i]包含所有匹配,但@987654354 @array 仅包含与该 regx 匹配的项目,我们可以使用 $i 索引将它们关联起来。

    if( !empty($match['tag'][$i])){
        //is a tag increment the result index
        ++$index;
    }

如果$match[tag][$i] 不为空。如果您在$i = 0 时查看$match[tag][0],您会发现它确实不是空的。在第二个循环中,$match[tag][1] 是空的,但 $match[prop_key][1] 不是,所以我们知道当 $i = 1 项目是 prop_key 匹配时。这就是它的工作原理。

-ps- 如果您能找到删除重复数字索引的方法,请与我分享...大声笑...如果我没有使用命名捕获组,这些是正常匹配,正如我所说它可能会变得混乱。

【讨论】:

  • 抱歉,我使用了您的代码并返回了一个空数组 Array()。我刚刚编辑了问题并修复了 m3u 文件内容的代码部分。你能再帮我一次吗?我需要标签 tvg-name group-title 和 url。省略“某事”标签。如果您能向我解释一下正则表达式,我将不胜感激。再次感谢您
  • 当您可以忽略它时,忽略它有什么意义。除了这些数据去哪里。
  • 好吧,假设我忽略它。但是代码仍然给我一个空数组。我更正了问题上的代码,您能帮我现在获取值吗?
  • 您可能对 HEREDOC 有问题,此位 $string = &lt;&lt;&lt;CUT 最后一部分 CUT; 必须是唯一的问题。 ; 之后没有空格,C 之前没有空格,否则它将不起作用。他们可能很敏感。但是因为字符串包含一个反引号 ` 它是它在代码中工作的唯一方式。
  • 你可以使用 CURL 的结果 $response 而不是 $string
【解决方案2】:

我在 php 中做了一个简单的工作 m3u8 解析器。 它是 json 的远程 m3u8 文件解析器,但很容易更改输出 https://github.com/onigetoc/m3u8-PHP-Parser

我可能很快会更改它或添加一个 CURL 解析器而不是 file_get_contents()。

m3u-parser.php?url=https://raw.githubusercontent.com/onigetoc/m3u8-PHP-Parser/master/ressources/demofile.m3u

【讨论】:

    【解决方案3】:

    一旦您获得 CURL 响应,然后通过 CURL 或 fopen 函数从远程位置读取文件。

    为此,您已从远程位置读取目录中的文件并将所有文件保存到本地服务器中。

    您可以使用文件功能“Stat”来获取所有信息并保存到$files中

    我已经给出了关于如何收集所有信息然后你可以创建数组的想法。

    创建数组后,您可以序列化响应以进行打印。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 2011-09-05
      • 2011-04-17
      • 2019-10-29
      • 2017-06-08
      • 2014-03-08
      • 1970-01-01
      相关资源
      最近更新 更多