iptv-checker

freearheyMIT更新放缓

用 Node.js 写的命令行工具,批量检测 IPTV 播放列表里的频道链接是否还能用,帮你快速筛掉失效源。

Node.js CLI tool for checking links in IPTV playlists

v0.30.3发布于 2026-03-06 14:15 UTC630star106fork同步于 2026-11-07 07:34 UTC

怎么上手

由 README 提炼,执行前请确认
npm install -g iptv-checker
iptv-checker /path-to-playlist/example.m3u
硬件要求按 README 说明

README 未说明硬件要求;工具依赖 ffprobe,需先在本机安装 ffmpeg/ffprobe,CPU 即可运行。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

用 ffprobe 批量检测 IPTV 播放列表里的频道链接是否可用,输出结构化结果

用 Node.js 写的命令行工具,批量检测 IPTV 播放列表里的频道链接是否还能用,帮你快速筛掉失效源。

核心能力

  • 基于 ffprobe 探测流,返回编解码与分辨率等元数据
  • 支持本地 m3u 文件、播放列表 URL 和 stdin 管道输入
  • 可调并发批大小、超时、重试与请求间隔
  • 支持 HTTP 代理、自定义 User-Agent 和跳过 SSL 校验
  • 提供 Node.js 模块 API,可挂 setUp/beforeEach/afterEach 钩子

容易踩的坑

必须先自行安装 ffprobe(ffmpeg),否则无法探测流;默认超时为 60000 毫秒,慢速源需手动调大;默认并发为 CPU 核心数,源站限流时需降低 parallel 或加 delay。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.30.3
  1. v0.30.3最新正式版2026-03-06 · 2026-03-06 14:15 UTC

    Fixes

  2. v0.30.22026-03-05 · 2026-03-05 13:21 UTC
    查看更新说明

    Fixes

    • fixes ERR_CHILD_PROCESS_STDIO_MAXBUFFER error
  3. v0.30.12026-03-04 · 2026-03-04 16:01 UTC
    查看更新说明

    Fixes

  4. v0.30.02026-03-02 · 2026-03-02 22:28 UTC
    查看更新说明

    Noticable Changes

    • offline streams and duplicates are now saved in a single file failed.m3u
    • the error message is now enclosed in square brackets
  5. v0.29.22026-03-02 · 2026-03-02 11:53 UTC
    查看更新说明

    Fixes

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    IPTV Checker Build Status

    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

    npm install -g iptv-checker
    
    Check local playlist file:
    iptv-checker /path-to-playlist/example.m3u
    
    Check playlist URL:
    iptv-checker https://some-playlist.lol/list.m3u
    
    Pipe playlist from stdin:
    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@[email protected]: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

    npm install iptv-checker
    
    Check playlist:
    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:

    {
      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:

    {
      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:
    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:

    {
      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:

    {
      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

    new IPTVChecker({
      timeout,
      parallel,
      delay,
      retry,
      userAgent,
      proxy,
      insecure,
      setUp,
      afterEach,
      beforeEach
    })
    

    Options:

    NameTypeDefaultDescription
    timeoutnumber60000The number of milliseconds before the request will be aborted
    parallelnumberCPU core countBatch size of channels to check concurrently
    delaynumber0Delay between requests in milliseconds
    retrynumber0The number of retries for failed requests
    userAgentstringIPTVChecker/0.29.0 (https://github.com/freearhey/iptv-checker)HTTP User-Agent
    proxystring''HTTP proxy to tunnel through (example: http://username@[email protected]:1234)
    insecurebooleanfalseAllow insecure connections when using SSL
    debugbooleanfalseEnable debug mode
    setUpfunction(playlist) => {}Runs before the start of the playlist check
    beforeEachfunction(stream) => {}Runs before the start of the stream check
    afterEachfunction(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.

    Contribution

    If you find a bug or want to contribute to the code or documentation, you can help by submitting an issue or a pull request.

    License

    MIT