Search code examples
phpxmlterminalm3u8

Convert m3u8 playlist files to XML list


I was wondering if there is any way to convert an M3U8 playlist to XML using Linux shell or PHP? For example.

M3U8 Playlist file

#EXTM3U
#EXTINF:-1 tvg-name="Canal 26" tvg-logo="https://demo.com/xDjOUuz.png" group-title="Argentina",
https://demolivevideo1.com/playlist.m3u8
#EXTINF:-1 tvg-name="LN"  tvg-logo="https://demo2.com/vJYzGt1.png" group-title="Argentina",
https://demolivevideo2.com/playlist.m3u8
#EXTINF:-1 tvg-name="ABC" tvg-logo="https://demo3.com/5CVl5EF.png" group-title="Australia",
https://demolivevideo3.com/playlist.m3u8

XML File structure after conversion.

<?xml version="1.0" encoding="utf-8"?>
<data>
  <channels>
    <name>Canal 26</name>
    <banner>https://demo.com/xDjOUuz.png</banner>
    <url>https://demolivevideo1.com/playlist.m3u8</url>
    <country>Australia</country>
  </channels>
  <channels>
    <name>LN</name>
    <banner>https://demo.com/xDjOUuz.png</banner>
    <url>https://demolivevideo2.com/playlist.m3u8</url>
    <country>Australia</country>
  </channels>
  <channels>
    <name>ABC</name>
    <banner>https://demo.com/xDjOUuz.png</banner>
    <url>https://demolivevideo3.com/playlist.m3u8</url>
    <country>Australia</country>
  </channels>
</data>

Solution

  • This is a bit (a lot, actually) of a hack (a few string replacements and splitting), but it should get you there, or close enough (in PHP):

    $m3u = '[your playlist above]
    ';            
    
    $newFile = '<?xml version="1.0" encoding="utf-8"?>
    <data></data>
    ';   
    
    $doc = new DOMDocument();
    $doc->loadXML($newFile);
    $xpath = new DOMXpath($doc);
    $destination = $xpath->query('/data');
    
    #some of the steps next can be combined, but I left them separate for readability
    $step1 = explode('#EXTINF:-1 ',str_replace('#EXTM3U','',$m3u));
    $step2 = array_slice($step1,1);
    
    foreach ($step2 as $item) {
        $step3 = str_replace('" ','" xxx',explode(',', $item));
        $step4 = explode('xxx',$step3[0]);
        $link = explode(',',$item)[1];
        $params = [];
        foreach ($step4 as $step)
           {
           $param = explode('=',$step)[1];
           array_push($params,$param);
           }
    
        #create you <channels> template
        $chan = "
        <channels>
        <name>{$params[0]}</name>
        <banner>{$params[1]}</banner>
        <url>{$link}</url>
        <country>{$params[2]}</country>  
        </channels>";
    
        $template = $doc->createDocumentFragment();
        $template->appendXML($chan);
        $destination[0]->appendChild($template);
           
    };
    
    echo $doc->saveXml();
    

    And that should be your expected output.