UNPKG

iptv-checker

Version:

Node.js CLI tool for checking links in IPTV playlists

417 lines (370 loc) 12.1 kB
# IPTV Checker [![Build Status](https://app.travis-ci.com/freearhey/iptv-checker.svg?branch=master)](https://app.travis-ci.com/freearhey/iptv-checker) Node.js CLI tool for checking links in IPTV playlists. This tool is based on the `ffprobe` library, so you need to install it on your computer first. You can find the right installer for your system here: https://www.ffmpeg.org/download.html ## Usage ### CLI ```sh npm install -g iptv-checker ``` #### Check local playlist file: ```sh iptv-checker /path-to-playlist/example.m3u ``` #### Check playlist URL: ```sh iptv-checker https://some-playlist.lol/list.m3u ``` #### Pipe playlist from `stdin`: ```sh cat ~/some-playlist.m3u | iptv-checker ``` Arguments: - `-o, --output`: output directory (default: `iptv-checker_20250314093952`) - `-t, --timeout`: the number of milliseconds before the request will be aborted (default: `60000`) - `-p, --parallel`: batch size of channels to check concurrently (default: CPU core count) - `-r, --retry`: the number of retries for failed requests (default: `0`) - `-d, --delay`: delay between requests in milliseconds (default: `0`) - `-x, --proxy`: HTTP proxy to tunnel through (example: `http://username@password@127.0.0.1:1234`) - `-a, --user-agent`: HTTP User-Agent (default: `IPTVChecker/0.29.0 (https://github.com/freearhey/iptv-checker)`) - `-k, --insecure`: allow insecure connections when using SSL (default: `false`) - `-D, --debug`: enable debug mode (default: `false`) ### Module ```sh npm install iptv-checker ``` #### Check playlist: ```js import { IPTVChecker } from 'iptv-checker' const checker = new IPTVChecker() // using playlist url checker.checkPlaylist('https://example.com/playlist.m3u').then(results => { console.log(results) }) // using local path checker.checkPlaylist('path/to/playlist.m3u').then(results => { console.log(results) }) // using playlist as string checker.checkPlaylist(string).then(results => { console.log(results) }) ``` #### Results _On success:_ ```js { header: { attrs: {}, raw: '#EXTM3U x-tvg-url=""' }, items: [ { name: 'KBSV/AssyriaSat (720p) [Not 24/7]', tvg: { id: 'KBSVAssyriaSat.us', name: '', logo: 'https://i.imgur.com/zEWSSdf.jpg', url: '', rec: '' }, group: { title: 'General' }, http: { referrer: '', 'user-agent': '' }, url: 'http://66.242.170.53/hls/live/temp/index.m3u8', raw: '#EXTINF:-1 tvg-id="KBSVAssyriaSat.us" tvg-logo="https://i.imgur.com/zEWSSdf.jpg" group-title="General",KBSV/AssyriaSat (720p) [Not 24/7]\r\nhttp://66.242.170.53/hls/live/temp/index.m3u8', line: 2, catchup: { type: '', days: '', source: '' }, timeshift: '', status: { ok: true, metadata: { streams: [ { index: 0, codec_name: 'h264', codec_long_name: 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10', profile: 'High', codec_type: 'video', codec_tag_string: '[27][0][0][0]', codec_tag: '0x001b', width: 1280, height: 720, coded_width: 1280, coded_height: 720, closed_captions: 0, has_b_frames: 2, pix_fmt: 'yuv420p', level: 31, chroma_location: 'left', refs: 1, is_avc: 'false', nal_length_size: '0', r_frame_rate: '30/1', avg_frame_rate: '0/0', time_base: '1/90000', start_pts: 943358850, start_time: '10481.765000', bits_per_raw_sample: '8', disposition: { default: 0, dub: 0, original: 0, comment: 0, lyrics: 0, karaoke: 0, forced: 0, hearing_impaired: 0, visual_impaired: 0, clean_effects: 0, attached_pic: 0, timed_thumbnails: 0 }, tags: { variant_bitrate: '400000' } }, //... ], format: { filename: 'http://66.242.170.53/hls/live/temp/index.m3u8', nb_streams: 2, nb_programs: 1, format_name: 'hls', format_long_name: 'Apple HTTP Live Streaming', start_time: '10481.560589', size: '214', probe_score: 100 }, requests: [ { method: 'GET', url: 'http://66.242.170.53/hls/live/temp/index.m3u8', headers: { 'User-Agent': 'Lavf/58.76.100', Accept: '*/*', Range: 'bytes=0-', Connection: 'close', Host: '66.242.170.53', 'Icy-MetaData': '1' } }, //... ] } } }, //... ] } ``` _On error:_ ```js { header: { attrs: {}, raw: '#EXTM3U x-tvg-url=""' }, items: [ { name: 'Addis TV (720p)', tvg: { id: 'AddisTV.et', name: '', logo: 'https://i.imgur.com/KAg6MOI.png', url: '', rec: '' }, group: { title: '' }, http: { referrer: '', 'user-agent': '' }, url: 'https://rrsatrtmp.tulix.tv/addis1/addis1multi.smil/playlist.m3u8', raw: '#EXTINF:-1 tvg-id="AddisTV.et" tvg-logo="https://i.imgur.com/KAg6MOI.png" group-title="Undefined",Addis TV (720p)\\r\\nhttps://rrsatrtmp.tulix.tv/addis1/addis1multi.smil/playlist.m3u8', line: 2, catchup: { type: '', days: '', source: '' }, timeshift: '', status: { ok: false, code: 'HTTP_REQUEST_TIMEOUT', message: 'HTTP 408 Request Timeout', } }, //... ] } ``` #### Check stream: ```js import { IPTVChecker } from 'iptv-checker' const checker = new IPTVChecker() // using stream url checker.checkStream('https://example.com/stream.m3u8').then(results => { console.log(results) }) // using stream object checker .checkStream({ url: 'https://example.com/stream.m3u8', http: { referrer: 'https://example.com', 'user-agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 9_7_6; en-US) Gecko/20100101 Firefox/69.5' } }) .then(results => { console.log(results) }) ``` #### Results _On success:_ ```js { url: 'https://example.com/stream.m3u8', http: { referrer: 'https://example.com', 'user-agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 9_7_6; en-US) Gecko/20100101 Firefox/69.5' }, status: { ok: true, metadata: { streams: [ { index: 0, codec_name: 'h264', codec_long_name: 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10', profile: 'High', codec_type: 'video', codec_tag_string: '[27][0][0][0]', codec_tag: '0x001b', width: 1280, height: 720, coded_width: 1280, coded_height: 720, closed_captions: 0, has_b_frames: 2, pix_fmt: 'yuv420p', level: 31, chroma_location: 'left', refs: 1, is_avc: 'false', nal_length_size: '0', r_frame_rate: '30/1', avg_frame_rate: '0/0', time_base: '1/90000', start_pts: 943358850, start_time: '10481.765000', bits_per_raw_sample: '8', disposition: { default: 0, dub: 0, original: 0, comment: 0, lyrics: 0, karaoke: 0, forced: 0, hearing_impaired: 0, visual_impaired: 0, clean_effects: 0, attached_pic: 0, timed_thumbnails: 0 }, tags: { variant_bitrate: '400000' } }, //... ], format: { filename: 'http://66.242.170.53/hls/live/temp/index.m3u8', nb_streams: 2, nb_programs: 1, format_name: 'hls', format_long_name: 'Apple HTTP Live Streaming', start_time: '10481.560589', size: '214', probe_score: 100 }, requests: [ { method: 'GET', url: 'http://66.242.170.53/hls/live/temp/index.m3u8', headers: { 'User-Agent': 'Lavf/58.76.100', Accept: '*/*', Range: 'bytes=0-', Connection: 'close', Host: '66.242.170.53', 'Icy-MetaData': '1' } }, //... ] } } } ``` _On error:_ ```js { url: 'https://example.com/stream.m3u8', http: { referrer: 'https://example.com', 'user-agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 9_7_6; en-US) Gecko/20100101 Firefox/69.5' }, status: { ok: false, code: 'HTTP_REQUEST_TIMEOUT', message: 'HTTP 408 Request Timeout', } } ``` ### Configuration ```js new IPTVChecker({ timeout, parallel, delay, retry, userAgent, proxy, insecure, setUp, afterEach, beforeEach }) ``` Options: | Name | Type | Default | Description | | ---------- | ---------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------- | | timeout | `number` | `60000` | The number of milliseconds before the request will be aborted | | parallel | `number` | CPU core count | Batch size of channels to check concurrently | | delay | `number` | `0` | Delay between requests in milliseconds | | retry | `number` | `0` | The number of retries for failed requests | | userAgent | `string` | `IPTVChecker/0.29.0 (https://github.com/freearhey/iptv-checker)` | HTTP User-Agent | | proxy | `string` | `''` | HTTP proxy to tunnel through (example: `http://username@password@127.0.0.1:1234`) | | insecure | `boolean` | `false` | Allow insecure connections when using SSL | | debug | `boolean` | `false` | Enable debug mode | | setUp | `function` | `(playlist) => {}` | Runs before the start of the playlist check | | beforeEach | `function` | `(stream) => {}` | Runs before the start of the stream check | | afterEach | `function` | `(stream) => {}` | Runs after the stream check is complete | ### Error codes A full list of the error codes used and their descriptions can be found [here](.readme/errors.md). ## Contribution If you find a bug or want to contribute to the code or documentation, you can help by submitting an [issue](https://github.com/freearhey/iptv-checker/issues) or a [pull request](https://github.com/freearhey/iptv-checker/pulls). ## License [MIT](LICENSE)