<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>zkkm2580 (火锅)</title>
    <link>https://pixman.io/zkkm2580</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>在 CF 上部署代码实现免梯观看 4gtv，并分享 4gtv 节目源。</title>
      <description>&lt;p&gt;很多喜欢看电视直播的小伙伴，手里都有台湾 4GTV 的直播源（M3U 列表）。但人在国内直连，往往会遇到两个让人抓狂的问题：&lt;/p&gt;

&lt;p&gt;网络筑墙：必须开启代理（挂梯子）才能加载和播放。
混合内容报错：很多播放器无法在 HTTPS 环境下直接播放 HTTP 协议的视频流分片。
今天就教大家一个完全免费、无需服务器的终极解决方案——利用 Cloudflare Worker 搭建一个属于你自己的流媒体中转站。只要部署一次，全家设备不用挂梯子，直接用 IPTV 播放器就能流畅观看！&lt;/p&gt;

&lt;p&gt;💡 核心原理
普通的代理只能帮你代理 M3U 文本列表，播放器拿到列表后，去拉取真正的视频数据（TS 分片）时依然会卡死。&lt;/p&gt;

&lt;p&gt;我们这个方案的强悍之处在于：让 Cloudflare 的海外节点化身“全职保姆”，在后台实时帮你抓取并下载视频流数据，再用“Stream 流式管道”实时同步传回给国内的播放器。相当于 Cloudflare 成了你的专属海外加速中转站！&lt;/p&gt;

&lt;p&gt;🛠️ 核心代码部署步骤
第一步：复制专属中转脚本 (worker.js)
登录你的 Cloudflare 后台，创建一个新的 Worker，将原有的代码全部清空，复制并粘贴以下优化版的流媒体中转代码：&lt;/p&gt;

&lt;p&gt;export default {
  async fetch(request, env, ctx) {
    // &lt;img title=":dart:" alt="🎯" src="https://twemoji.ruby-china.com/2/svg/1f3af.svg" class="twemoji"&gt; 替换为你手里的 4GTV 原始 M3U 播放列表地址
    const targetUrl = "http://&lt;em&gt;.&lt;/em&gt;.&lt;em&gt;.&lt;/em&gt;：**/4.m3u";
    const url = new URL(request.url);&lt;/p&gt;

&lt;p&gt;const fakeHeaders = {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
      "Accept": "&lt;em&gt;/&lt;/em&gt;",
      "Accept-Language": "en-US,en;q=0.9",
      "Connection": "keep-alive"
    };&lt;/p&gt;

&lt;p&gt;const tsUrl = url.searchParams.get("ts");
    if (tsUrl) {
      try {
        const decodedUrl = decodeURIComponent(tsUrl);&lt;/p&gt;

&lt;p&gt;const tsResponse = await fetch(decodedUrl, {
          method: "GET",
          headers: fakeHeaders,
          redirect: "follow",
          cf: { cacheEverything: false, cacheTtl: 0 }
        });&lt;/p&gt;

&lt;p&gt;if (!tsResponse.ok) {
          return new Response(&lt;code&gt;Fetch TS failed: ${tsResponse.status}&lt;/code&gt;, { status: tsResponse.status });
        }&lt;/p&gt;

&lt;p&gt;const { readable, writable } = new TransformStream();
        tsResponse.body.pipeTo(writable);&lt;/p&gt;

&lt;p&gt;return new Response(readable, {
          status: tsResponse.status,
          statusText: tsResponse.statusText,
          headers: {
            "Content-Type": tsResponse.headers.get("Content-Type") || "video/mp2t",
            "Access-Control-Allow-Origin": "*",
            "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
            "Pragma": "no-cache"
          }
        });&lt;/p&gt;

&lt;p&gt;} catch (e) {
        return new Response("Proxy TS Error: " + e.message, { status: 500 });
      }
    }&lt;/p&gt;

&lt;p&gt;try {
      const response = await fetch(targetUrl, {
        method: "GET",
        headers: fakeHeaders,
        cf: { cacheEverything: false, cacheTtl: 0 }
      });&lt;/p&gt;

&lt;p&gt;if (!response.ok) {
        return new Response(&lt;code&gt;Target M3U status: ${response.status}&lt;/code&gt;, { status: response.status });
      }&lt;/p&gt;

&lt;p&gt;let text = await response.text();
      const baseUrl = new URL(targetUrl);
      const lines = text.split("\n");&lt;/p&gt;

&lt;p&gt;const rewrittenLines = lines.map(line =&amp;gt; {
        const trimmed = line.trim();
        if (trimmed === "" || trimmed.startsWith("#")) return line;&lt;/p&gt;

&lt;p&gt;let absoluteTsUrl = trimmed;
        try {
          absoluteTsUrl = new URL(trmmed, baseUrl.href).href;
        } catch (e) {
          return line; 
        }&lt;/p&gt;

&lt;p&gt;return &lt;code&gt;${url.origin}${url.pathname}?ts=${encodeURIComponent(absoluteTsUrl)}&lt;/code&gt;;
      });&lt;/p&gt;

&lt;p&gt;return new Response(rewrittenLines.join("\n"), {
        status: 200,
        headers: {
          "Content-Type": "application/x-mpegURL; charset=utf-8",
          "Access-Control-Allow-Origin": "*",
          "Cache-Control": "no-store, no-cache, must-revalidate"
        }
      });&lt;/p&gt;

&lt;p&gt;} catch (error) {
      return new Response("Proxy M3U Error: " + error.message, { status: 500 });
    }
  }
};
第二步：保存并绑定域名
代码粘贴完成后，点击右上角的 Save and Deploy（保存并部署）。
&lt;img title=":warning:" alt="⚠" src="https://twemoji.ruby-china.com/2/svg/26a0.svg" class="twemoji"&gt;️ 避坑关键点：Cloudflare 默认赠送的 *.workers.dev 免费域名在国内遭到了严重的网络干扰。请务必在 Worker 详情页的 Settings -&amp;gt; Triggers -&amp;gt; Custom Domains（自定义域名）中，绑定一个你自己拥有的、国内可正常直连的域名（例如 4gtvc.yourdomain.com）。
&lt;img title=":tv:" alt="📺" src="https://twemoji.ruby-china.com/2/svg/1f4fa.svg" class="twemoji"&gt; 怎么使用？
绑定好你自己的自定义域名后，你的专属直播源地址就诞生了！它会长成这样：
https://你的自定义域名.com/&lt;/p&gt;

&lt;p&gt;打开你常用的 IPTV 播放器（如电脑端的 PotPlayer、VLC，电视盒子的 IPTV Pro，或者手机端播放器），直接将你的自定义域名网址当做 M3U 链接添加进去。&lt;/p&gt;

&lt;p&gt;点击播放，你会发现——关闭梯子，电视直播也一样秒开、丝滑、不卡顿！&lt;/p&gt;

&lt;p&gt;免费额度：Cloudflare Worker 免费版每天提供 10 万次 免费请求额度，对于个人或家庭日常看电视来说完全是用不完的。
安全性：代码中加入了强力的跨域头（CORS）和严格的缓存控制，能完美兼容目前市面上所有的 Web 网页播放器和各类盒子客户端。&lt;/p&gt;

&lt;p&gt;4gtv 节目源：
链接：&lt;a href="https://pan.baidu.com/s/1fUL4qK6RqtrzivTOD5eLSg?pwd=4w87" rel="nofollow" target="_blank"&gt;https://pan.baidu.com/s/1fUL4qK6RqtrzivTOD5eLSg?pwd=4w87&lt;/a&gt; 提取码：4w87 
上述代码帖出来乱七八九的，我做成文件复制粘帖，需要的下载：4gtv 在 cloudflare 部署.zip
链接： &lt;a href="https://pan.baidu.com/s/1S6rTA_agbFZ2u0HnEViMyA?pwd=zn86" rel="nofollow" target="_blank"&gt;https://pan.baidu.com/s/1S6rTA_agbFZ2u0HnEViMyA?pwd=zn86&lt;/a&gt; 提取码：zn86&lt;/p&gt;</description>
      <author>zkkm2580</author>
      <pubDate>Sat, 20 Jun 2026 12:48:33 +0800</pubDate>
      <link>https://pixman.io/topics/738</link>
      <guid>https://pixman.io/topics/738</guid>
    </item>
    <item>
      <title>4gtv 如何外网收看？</title>
      <description>&lt;p&gt;内网观看正常，但映射端口后外网无法观看，如何解决？也无法用 tvheadend 转发。&lt;/p&gt;</description>
      <author>zkkm2580</author>
      <pubDate>Tue, 04 Jun 2024 16:37:13 +0800</pubDate>
      <link>https://pixman.io/topics/26</link>
      <guid>https://pixman.io/topics/26</guid>
    </item>
  </channel>
</rss>
