zikwall/m3u-content-parser

There is no license information available for the latest version (dev-master) of this package.

dev-master 2022-04-06 12:35 UTC

This package is auto-updated.

Last update: 2024-04-06 16:51:09 UTC


README

Minimalistic, functional and easy to use playlist parser

Example usage

use zikwall\m3ucontentparser\M3UContentParser;
use zikwall\m3ucontentparser\M3UItem;

$parser = new M3UContentParser('https://iptv-org.github.io/iptv/countries/ru.m3u');
$parser->parse();

foreach ($parser->limit(20)->all() as $item) {
    /**
     * @var $item M3UItem
     */
    echo
        $item->getTvgName(),    PHP_EOL,
        $item->getTvgLogo(),    PHP_EOL,
        $item->getTvgUrl(),     PHP_EOL,
        $item->getGroupTitle(), PHP_EOL,
        $item->getId(),         PHP_EOL;
        $item->getGroupId(),    PHP_EOL,
        $item->getLanguage(),   PHP_EOL,
        $item->getCountry();
}

More example

// rewrite current m3u content
foreach ($parser->all() as $item) {
    /**
     * @var $item M3UItem
     */
     $item
             ->replaceTvgName('UNNAMED ITEM')
             ->replaceTvgLogo('NEW LOGO URL')
             ->replaceTvgUrl('CHANE NEW URL');   
}

echo $parser->rewriteM3UFile();

output example:
#EXTM3U url-tvg="http://iptvx.one/epg/epg.xml.gz"
#EXTINF:-1 group-title="Новости",UNNAMED ITEM
CHANE NEW URL
#EXTINF:-1 group-title="Новости",UNNAMED ITEM
CHANE NEW URL

Segment Parser

use zikwall\m3ucontentparser\SegmentM3U;
$segmant = new SegmentM3U();
$fragment->attachSource('examples/segments/index.m3u8')->parse();

print_r($segment->getFragments());
print_r($segment->getSegments());
print_r($segment->getTime());
var_dump($segment->getIsEnding());

Complex sample

use zikwall\m3ucontentparser\M3UContentParser;
use zikwall\m3ucontentparser\SegmentM3U;
use zikwall\m3ucontentparser\M3UItem;
use zikwall\m3ucontentparser\FragmentM3UItem;

$parser = new M3UContentParser('https://iptv-org.github.io/iptv/countries/ru.m3u');
$parser->parse();

foreach ($parser->limit(10)->offset(10)->all() as $item) {
    /**
     * @var $item M3UItem
     */
    $segment = new SegmentM3U();
    $segment->attachSource($item->getTvgUrl())->parse();

    if ($segment->getIsFragmentSource() === true) {
        /**
         * @var $fragment FragmentM3UItem
         */
        echo $segment->getCleanSource(), PHP_EOL;
        foreach ($segment->getFragments() as $fragment) {
            $subSegment = new SegmentM3U();
            $subSegment->attachSource($segment->getNewSource($fragment->fragment))->parse();

            echo $segment->getNewSource($fragment->fragment), PHP_EOL;
        }

        continue;
    }

    // ... conventional segment processing
    foreach ($segment->getSegments() as $segmentItem) {
        /**
         * @var $segmentItem SegmentM3UItem
         */
        echo $segment->getNewSource($segmentItem->segment), PHP_EOL;
//        display generated chunk links
//        http://xxxxx/stream8/stream2020_2_23_13_44_7-65006.ts
//        http://xxxxx/stream8/stream2020_2_23_13_44_18-65007.ts
//        http://xxxxx/stream8/stream2020_2_23_13_44_28-65008.ts
//        ...
    }
}

Seemed complicated? It is even easier!

$segment = new SegmentM3U();
$segment->attachSource('http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/variable.m3u8')->parse();

if ($segment->getIsFragmentSource() === true) {
    $segments = [];
    foreach ($segment->getFragments() as $fragment) {
        $subSegment = new SegmentM3U();
        $subSegment->attachSource($segment->getNewSource($fragment->fragment))->parse();

        echo $segment->getNewSource($fragment->fragment), PHP_EOL;

        /**
         * Get total duration
         */
        echo sprintf('Duration is: %0.2f seconds', $subSegment->getDuration()), PHP_EOL;

        foreach ($subSegment->getSegments() as $sgmt) {
            echo $subSegment->getNewSource($sgmt->segment), PHP_EOL;
        }
    }

    /**
     * Original: http://mhd.xxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/variable.m3u8
     * Cleaning: http://mhd.xxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vl2w/
     *
     * Return stream links (FRAGMENTS):
     *  - http://mhd.xxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vl2w/playlist.m3u8 // LOW
     *  - http://mhd.xxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vm2w/playlist.m3u8 // MIDDLE
     *  - http://mhd.xxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/playlist.m3u8 // HIGH
     */

    /**
     * Each all fragments return SegmentM3UItem Object
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/playlist.m3u8
     *
     * Array
     *  (
     *      [0] => zikwall\m3ucontentparser\SegmentM3UItem Object
     *      (
     *          [duration] => 6
     *          [segment] => segment-1582439833-08914115.ts
     *      )
     *      [1] => zikwall\m3ucontentparser\SegmentM3UItem Object
     *      (
     *          [duration] => 6
     *          [segment] => segment-1582439833-08914116.ts
     *      )
     *      ...
     */

    /**
     * Convert to valid links, example:
     *
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914207.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914208.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914209.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914210.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914211.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914212.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914213.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914214.ts
     * http://mhd.xxxxxxx.tv/p/k5OqlMqeQONvANUJOq9GFQ,1582553567/streaming/ntvnn/324/vh1w/segment-1582439833-08914215.ts
     */
}

Even easier

$segment = new SegmentM3U();
$segment->attachSource('http://hls.kinoplayer.co/hls/PaSSagir.iz.SanFranCissko.2O17.HDRip/playlist.m3u8')->parse();

foreach ($segment->getSegments() as $sgmt) {
    echo $segment->getNewSource($sgmt->segment), PHP_EOL;
}

echo sprintf('Duration is: %0.2f seconds', $segment->getDuration()), PHP_EOL;

More examples Segment parser

You can try different combinations of examples yourself

API

  1. The parser constructor accepts a link or file path:
$parser = new M3UContentParser('https://iptv-org.github.io/iptv/countries/ru.m3u');
  1. Parsing is called by the same method:
$parser->parse();

Methods in m3u parser

  • getCahce()
  • getResfresh()
  • getTvgUrl()
  • limit(int)
  • offset(int)
  • all()
  • getItems()
  • rewriteM3UFile()

Methods in m3u item object

  • getId()
  • getTvgId()
  • getTvgName()
  • getTvgUrl()
  • getTvgLogo()
  • getTvgShift()
  • getGroupId()
  • getGroupTitle()
  • getExtGrp()
  • getCensored()
  • getLanguage()
  • getCountry()
  • getAudioTrack()
  • getAudioTrackNum()
  • getExtraAttributes()

API Segment

  • getFragments() return array of tracks with props
  • getSegments() return array of segments in track
  • getTime() return array of timecodes: hours, minutes, seconds and string format HH:MM:SS & original value
  • getDuration() return float value duration of seconds
  • getIsEnding() return bool value, indicates whether the stream has an ending or not
  • getIsFragmentSource()
  • getNewSource(string $sub_source)
  • getHashHeaders()
  • getDirtyItems()

Installation

composer require zikwall/m3u-content-parser

Develop Mode

{
    "minimum-stability": "dev",
    "repositories": [
        {
            "type": "git",
            "url": "https://github.com/zikwall/m3u-content-parser.git"
        }
    ],
    "require": {
        "zikwall/m3u-content-parser": "dev-master"
    }
}

Questions?

For all questions and suggestions - welcome to Issues