gemorroj / m3u-parser
m3u playlist parser/generator
Installs: 51 712
Dependents: 1
Suggesters: 0
Security: 0
Stars: 82
Watchers: 8
Forks: 32
Open Issues: 5
Requires
- php: >=8.0.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.41
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6
README
Requirements:
- PHP >= 8.0.2
Installation:
composer require gemorroj/m3u-parser
Example parser:
<?php declare(strict_types=1); use M3uParser\M3uParser; $m3uParser = new M3uParser(); $m3uParser->addDefaultTags(); $data = $m3uParser->parseFile('path_to_file.m3u'); // or $data = $m3uParser->parse('playlist content'); print_r($data->getAttributes()); /* Array ( [url-tvg] => http://www.teleguide.info/download/new3/jtv.zip [m3uautoload] => 1 [deinterlace] => 8 [cache] => 500 ) */ /** @var \M3uParser\M3uEntry $entry */ foreach ($data as $entry) { print_r($entry); /* M3uParser\M3uEntry Object ( [lineDelimiter:protected] => [extTags:M3uParser\M3uEntry:private] => Array ( [0] => M3uParser\Tag\ExtInf Object ( [title:M3uParser\Tag\ExtInf:private] => TV SLO 1 HD [duration:M3uParser\Tag\ExtInf:private] => 1 [attributes:M3uParser\Tag\ExtInf:private] => Array ( ) ) [1] => M3uParser\Tag\ExtTv Object ( [tags:M3uParser\Tag\ExtTv:private] => Array ( [0] => Slovenski [1] => HD ) [language:M3uParser\Tag\ExtTv:private] => slv [xmlTvId:M3uParser\Tag\ExtTv:private] => SLO1HD [iconUrl:M3uParser\Tag\ExtTv:private] => ) ) [path:M3uParser\M3uEntry:private] => rtp://@232.2.201.53:5003 ) */ echo $entry->getPath() . "\n"; foreach ($entry->getExtTags() as $extTag) { switch ($extTag) { case $extTag instanceof \M3uParser\Tag\ExtInf: // If EXTINF tag echo $extTag->getTitle() . "\n"; echo $extTag->getDuration() . "\n"; if ($extTag->hasAttribute('tvg-name')) { // If tvg-name attribute in EXTINF tag echo $extTag->getAttribute('tvg-name') . "\n"; } break; case $extTag instanceof \M3uParser\Tag\ExtTv: // If EXTTV tag echo $extTag->getXmlTvId() . "\n"; echo $extTag->getIconUrl() . "\n"; echo $extTag->getLanguage() . "\n"; foreach ($extTag->getTags() as $tag) { echo $tag . "\n"; } break; case $extTag instanceof \M3uParser\Tag\ExtLogo: // If EXTLOGO tag echo $extTag->getLogo() . "\n"; break; case $extTag instanceof \M3uParser\Tag\ExtVlcOpt: // If EXTVLCOPT tag echo $extTag->getKey() . ':' . $extTag->getValue() . "\n"; break; case $extTag instanceof \M3uParser\Tag\ExtGrp: // If EXTGRP tag echo $extTag->getValue() . "\n"; break; case $extTag instanceof \M3uParser\Tag\Playlist: // If PLAYLIST tag echo $extTag->getValue() . "\n"; break; case $extTag instanceof \M3uParser\Tag\ExtTitle: // If EXTTITLE tag echo $extTag->getValue() . "\n"; break; case $extTag instanceof \M3uParser\Tag\ExtAlbumArtUrl: // If EXTALBUMARTURL tag echo $extTag->getValue() . "\n"; break; } } }
Example generator:
<?php declare(strict_types=1); use M3uParser\M3uData; use M3uParser\M3uEntry; use M3uParser\Tag\ExtInf; use M3uParser\Tag\ExtTv; use M3uParser\Tag\ExtLogo; use M3uParser\Tag\ExtVlcOpt; use M3uParser\Tag\ExtGrp; use M3uParser\Tag\Playlist; use M3uParser\Tag\ExtTitle; use M3uParser\Tag\ExtAlbumArtUrl; $entry = new M3uEntry(); $entry->setPath('test-path'); $entry->addExtTag( (new ExtInf()) ->setDuration(123) ->setTitle('extinf-title') ->setAttribute('test-attr', 'test-attrname') ); $entry->addExtTag( (new ExtTv()) ->setIconUrl('https://example.org/icon.png') ->setLanguage('ru') ->setXmlTvId('xml-tv-id') ->setTags(['hd', 'sd']) ); $entry->addExtTag( (new ExtLogo()) ->setLogo('https://example.org/logo.png') ); $entry->addExtTag( (new ExtVlcOpt()) ->setKey('http-user-agent') ->setValue('M2uParser') ); $entry->addExtTag( (new ExtGrp()) ->setValue('Rock') ); $entry->addExtTag( (new Playlist()) ->setValue('My favorite playlist') ); $entry->addExtTag( (new ExtTitle()) ->setValue('title') ); $entry->addExtTag( (new ExtAlbumArtUrl()) ->setValue('https://store.example.com/download/A32X5yz-1.jpg') ); $data = new M3uData(); $data->setAttribute('test-name', 'test-value'); $data->append($entry); echo $data; /* #EXTM3U test-name="test-value" #EXTINF:123 test-attr="test-attrname", extinf-title #EXTTV:hd,sd;ru;xml-tv-id;https://example.org/icon.png #EXTLOGO:https://example.org/logo.png #EXTVLCOPT:http-user-agent=M2uParser #EXTGRP:Rock #PLAYLIST:My favorite playlist #EXTTITLE:title #EXTALBUMARTURL:https://store.example.com/download/A32X5yz-1.jpg test-path */
Example custom tag:
#EXTM3U
#EXTCUSTOMTAG:123
http://nullwave.barricade.lan:8000/club
implement ExtTagInterface
interface
<?php use M3uParser\M3uParser; use M3uParser\Tag\ExtTagInterface; // create custom tag class ExtCustomTag implements ExtTagInterface { /** * @var string */ private $data; /** * #EXTCUSTOMTAG:data */ public function __construct(?string $lineStr = null) { if (null !== $lineStr) { $this->makeData($lineStr); } } protected function makeData(string $lineStr): void { /* EXTCUSTOMTAG format: #EXTCUSTOMTAG:data example: #EXTCUSTOMTAG:123 */ $data = \substr($lineStr, \strlen('#EXTCUSTOMTAG:')); $this->setData(\trim($data)); } public function getData(): string { return $this->data; } public function setData(string $data): self { $this->data = $data; return $this; } public function __toString(): string { return '#EXTCUSTOMTAG:' . $this->getData(); } public static function isMatch(string $lineStr): bool { return 0 === \stripos($lineStr, '#EXTCUSTOMTAG:'); } } // use custom tag $m3uParser = new M3uParser(); $m3uParser->addTag(ExtCustomTag::class); // add custom tag $data = $m3uParser->parseFile('path_to_file.m3u'); print_r($data); /* M3uParser\M3uData Object ( [attributes:M3uParser\M3uData:private] => Array ( ) [storage:ArrayIterator:private] => Array ( [0] => M3uParser\M3uEntry Object ( [lineDelimiter:protected] => [extTags:M3uParser\M3uEntry:private] => Array ( [0] => M3uParser\Tests\ExtCustomTag Object ( [data:M3uParser\Tests\ExtCustomTag:private] => 123 ) ) [path:M3uParser\M3uEntry:private] => http://nullwave.barricade.lan:8000/club ) ) ) */