自动抓取IPTV单播地址,实现时移回看(二)

Openwrt 通过策略路由收看IPTV单播链接的详细介绍。获取IPTV的IP,自动获取单播时移地址、自动生成M3U文件、fcc快速换台、完美实现时移和回看。

上篇写到如何通过策略路由,使得可以局域网内播放单播rtsp视频。由于局域网内客户端对rstp视频支持不够友好,使得无法直接使用rtsp地址。这时候我们就需要通过rtp2httpd这个软件,将rtsp代理转发给下游客户端。

四、RTP2HTTPD 代理转发

rtp2httpd官方github开源软件地址:https://github.com/stackia/rtp2httpd

自动抓取IPTV单播地址,实现时移回看(二)

路由器上安装也是比较简单的,这点rtp2httpd 比其他开源软件做的好,Openwrt路由器上一键安装脚本:

wget -O - https://raw.githubusercontent.com/stackia/rtp2httpd/main/scripts/install-openwrt.sh | sh

安装完成后,在 LuCI 管理界面的 “服务” 菜单中找到 “rtp2httpd” 进行配置。每次更新版本后如果 LuCI 出现工作异常,需要 Ctrl+F5 刷新 或 清空浏览器缓存 或 使用无痕模式访问 解决。如果通过 OpenWrt 源码构建直接把 rtp2httpd 编译到固件里,可以把该仓库地址加入到 feeds.conf.default 文件,加入

src-git rtp2httpd https://github.com/stackia/rtp2httpd.git

运行 ./scripts/feeds update rtp2httpd ./scripts/feeds install rtp2httpd 更新 feed。

运行 make menuconfig,找到 LuCI -> Applications -> luci-app-rtp2httpd,将其勾选 ,保存退出。

运行 make -j8 ,即可编译路由器固件。rtp2httpd 访问iptv服务器用的useragent是:”rtp2httpd/版本号“,我们可以修改rtp2httpd/src/rtsp.c 文件,将约29行 #define USER_AGENT "rtp2httpd/" VERSION 修改为 #define USER_AGENT "机顶盒种rtsp服务的useragent",wireshark抓包数据里有。这样可以使得iptv服务器认为是盒子在和它通信,而不是rtp2httpd程序。(最新版已经可以设置useragent了,因此无需修改源码)。rtp2httpd使用比较简单,相当不错。没有社么好说的。有问题多看几次该项目说明和Issues。

自动抓取IPTV单播地址,实现时移回看(二)

rtpshttpd网页播放、回看也没问题,

五、M3U文件编制及TIVIMATE的使用

tivimate要能看回放及时移,需要配置好M3U文件。M3U文件基本格式如下:

无需鉴权M3U文件示例:

#EXTINF:-1 tvg-name="CCTV1" catchup="default" catchup-source="rtsp://220.167.81.247/PLTV/88888896/224/3221228807/10000100000000060000000003732597_0.smil?playseek={utc:YmdHMS}-{utcend:YmdHMS}",CCTV1综合
http://192.168.3.2:5140/223.94.0.31:5140?fcc=220.167.81.247:8027

含有鉴权参数的M3U文件示例:

#EXTINF:-1 tvg-name="CCTV1" catchup="default" catchup-source="rtsp://123.147.112.152:1554/iptv/import/Tvod/iptv/001/040000010400000200000001/01000000004000000000000000000231.rsc/24067_Uni.sdp?lvst=3&nodeid=iptvnode109&TSTVTimeLife=7200&userid=&userip=220.200.73.191&time=20251028171008.120+00&life=86400000&transferproviderid=040000010400000200000001&ctype=01&sid=208291671&purl=MTIzLjE0Ny4xMTIuMTUwOjU1NC8wNDAwMDAwMS8wMTAwMDAwMDAwNDAwMDAwMDAwMDAwMDAwMDAwMDIzMT8&domain=0&phycid=01000000004000000000000000000231&playtype=1&urtm=0&agnt=MTIzLjE0Ny4xMTIuMTUwOjU1NA&sadr=MTIzLjE0Ny4xMTIuMTUy&iptvsessionid=Agent1661120251028171008125090&cryptmode=0502&crypt=3221E7F9A6E4909B75F204E2605D07C0&playseek={utc:YmdHMS}-{utcend:YmdHMS}
http://192.168.3.2:5140/223.94.0.31:5140?fcc=220.167.81.247:8027

第一行是EXTINF信息行(频道信息行),比较重要的是catchup="default" catchup-source="单播地址",当你回放或时移时会用该单播地址播放。

第二行是 媒体播放地址,一般写入组播地址,可以快速播放,这是直播LIVE地址。如果需要FCC 快速换台,在组播地址后方加入 ?fcc=fcc服务器:端口号

注意点:

1、playseek={utc:YmdHMS}-{utcend:YmdHMS} 是时移参数,播放器会自动填充数值,拖动进度条,就会变为playseek=20260119090655-20260119090928。要看回放需搞清本地IPTV服务器到底用的是UTC时间还是本地时间(UTC+8)。playseek={utc:YmdHMS}-{utcend:YmdHMS} 这是UTC时间。如果不能播放,可以用playseek={(b)YmdHMS}-{(e)YmdHMS} 尝试,这是本地时间(UTC+8)。对于IPTV服务器用的Unix 时间戳,则应该为 playseek=${(b)timestamp}-${(e)timestamp} 。还有用 playseek={utc}-{utcend} UTC,ISO8601 格式的。有的iptv服务器还不认 playseek ,需要改为 tvdr ,也就是 ?tvdr={utc:YmdHMS}-{utcend:YmdHMS} 。具体如何设置,多多尝试或搜索本地用户的文章。具体可查看 https://github.com/stackia/rtp2httpd/blob/main/docs/m3u-integration.md

2、catchup=”default” 播放器 直接使用 catchup-source 后的链接地址。

这个catchup还可以写为catchup=”append” catchup-source=”?playseek={utc:YmdHMS}-{utcend:YmdHMS}”,(如果下方 媒体播放地址 中含有?此处就不能写 ?应该改为 & ,链接中最多一个?,表示后面的是各种参数)
这就表明播放器播放时移单播视频的时候,用的是 组合媒体播放地址+catchup-source 组合的链接,也就是最后链接为:
http://192.168.3.2:5140/223.94.0.31:5140?playseek={utc:YmdHMS}-{utcend:YmdHMS}。
含有fcc快速播放的地址也是:
http://192.168.3.2:5140/223.94.0.31:5140?playseek={utc:YmdHMS}-{utcend:YmdHMS} 。

rtp2httpd会自动转换url地址,写的不合理,就会无法播放。

如果你写成:
#EXTINF:-1 tvg-name=”CCTV1″ catchup=”append” catchup-source=”rtsp://220.167.81.247/PLTV/88888896/224/3221228807/1003732597_0.smil?authinfo=”1234″&playseek={utc:YmdHMS}-{utcend:YmdHMS}”,CCTV1综合
http://192.168.3.2:5140/223.94.0.31:5140?fcc=220.167.81.247:8027

那么经过rtp2httpd转换成的单播url就变为 :
/223.94.0.31:5140/rtsp/220.167.81.247/PLTV/88888896/224/3221228807/1003732597_0.smil?authinfo=”1234″&playseek={utc:YmdHMS}-{utcend:YmdHMS}
那么显然是无法播放的。

所以尽量不要用 catchup=”append” 。

Tivimate使用的难点

我则是正版tivimate,tivimate还是不支持直接播放rtsp,写M3U文件这里 catchup-source 可以采用rtp2httd的http流格式:
catchup-source="http://192.168.1.1:5140/rtsp/1.2.3.4/1/000011234?AuthInfo=azBUz&playseek={utc:YmdHMS}-{utcend:YmdHMS}" 。不能直接写成 rtsp://220.167.81.247:554/....../?....playseek={utc:YmdHMS}-{utcend:YmdHMS} ,这种播放不了。

一顿操作下来,以为稳稳地可以时移观看了,实际tivimate种无法时移,但是可以回放几小时前的内容。这就奇怪了,明明rtp2httpd的网页播放器可以实现时移,但是到我这里就不行,网上也没有我这种情况的帖子。

对rtp2httpd的网页播放器 进行F12 浏览器分析,粗略发现它发送的时间格式是 playseek=UTC时移的时间-UTC当前时间 。看rtp2httpd 的日志,tivimata 播放连接中是 playseek=时移的时间-epg节目结束时间

看来是时间有误,将参数改为 playseek={utc:YmdHMS}-{now:YmdHMS} 也就是 节目开始时间-当前时间 ,这下怪了,连rtp2httpd的网页播放器 也不能播放了,tivimate更不用说了。查看了很多tivimate使用的格式,很多都说用 playseek=${(b)yyyyMMddHHmmss}-${(e)yyyyMMddHHmmss} (节目开始时间-epg节目本地结束时间),测试了下,tivimate 连时间解析都解析不出来,直接发送链接 http://192.168.1.1:5140/rtsp/....../?...&playseek={(b)yyyyMMddHHmmss}-{(e)yyyyMMddHHmmss} 到rtp2httpd服务端了。修改 tivimate User Agent 设置,加上 TZ/UTC+8 ,rtp2httpd将识别为国内时区,回放时移倒是可以了,但是是8小时前的节目。将这下凌乱了,难道是tivimate 不支持还是时移地址不对抑或是M3U文件写法有问题?到reddit tivimate论坛搜索了以下,没人碰到此等问题, 为解决此问题,各种方法测试了一天还是无解。

第二天,总结并详细了解了关于时间占位符的各种设定,痛定思痛,决定分析 rtp2httpd的网页播放器 的js脚本,看看为什么网页端可以时移,它采取了什么措施。原来 rtp2httpd 对时移采用了如下处理,它取 epg节目结束时间和当前时间的最小值,并减去10秒作为最终endtime。本地IPTV服务器不接受未来时间和当前时间,endtime 最多是当前时间-10s。如此就顺利找到了解决此问题的方法。时移回看改为:playseek={utc:YmdHMS}-{lutc:YmdHMS}&r2h-seek-offset=-15,多给了5秒,也就是 UTC时移的时间—–UTC当前时间-15s。可惜tivimate不支持这种取最小值的方法,但是不影响观看,现在7天回放都可以了,问题圆满解决。在实际观看中,发现tivimate时移几分钟前的节目会略有卡顿,可能是tivimate在重新生成播放链接请求IPTV服务器或这个-15s在作怪。

六、自动获取IPTV单播地址

我这里IPTV单播带鉴权的地址鉴权信息估计有有效期(还没尝试到过7天后鉴权信息是否有效),不能获取到新的鉴权信息过段时间rtsp地址将无法播放。IPTV口IP信息发生变化也无法用原来的rtsp链接,需要重新生成新的带鉴权的rtsp单播链接。这里参考了这篇帖子 https://www.right.com.cn/forum/thread-8314231-1-1.html 。根据wireshark抓包数据里的地址及POST、GET所用参数用shell 模拟盒子获得鉴权信息。过程总体是顺利的,有了AI,DES3 ECB 加密生成密文UserToken 成为了可能。下面就是半天时间写的脚本,各种值的说明脚本里都有,如果你需要可以根据你wireshark抓包的数据进行分析,wireshark 输入框里输入 ip.addr == 盒子ip &&(http||rtsp) 进行查找。

自动抓取IPTV单播地址,实现时移回看(二)

这个版本只是自动生成了简单的m3u播放文件和简单的文本文件。并没有考虑台标等这些问题,可以用一个M3U模板,然后脚本修改替换单播信息,实际我也是这么处理的,由于M3U模板各不一致,就不放出来了。

#!/bin/sh

############################
# 必填(抓包 / 盒子获取)
############################
KEY=""                             # iptv密码,8位
USERID=""                          # IPTV账号,不含@vod,后面拼接了@vod
STBID=""                           # 机顶盒序列号,如:2A000000000000000000000000000060,机顶盒铭牌出或抓包处有
MAC=""                             # 机顶盒MAC地址
GOT_FILE="/usr/share/myfile/iptv"  # 自定义保存的各种网页文件、TOKEN等
ITV_HOST=""                        # 认证服务器地址,GET /auth?UserID= 处的主机名,如:http://1.2.3.4:8298",非ip的域名注意用运行商dns解析
IPTVINTERFACE=""                   # IPTV网卡接口,如eth3、eth1.2等
USERAGENT=""                       # 机顶盒的用户代理,如:ZTC HUAWEI Resolution(PAL,720p,1080i) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7
ROUTEIP=""                         # rtp2httpd地址,格式 http://192.168.1.1:5140

echolog() {
    local d="$(date "+%Y-%m-%d %H:%M:%S")"
    echo "$d: [IPTV]$*" >> "/usr/share/myfile/iptv.log"
}

# 获取iptv接口ip,本例在eth4口上
get_iptvip() {
    IP=$(ip -4 addr show dev ${IPTVINTERFACE} scope global | awk '/inet / {print $2}' | cut -d/ -f1)
}

############################
# DES3 ECB 加密(HEX)
############################
des3_encrypt() {
  # params: plaintext (string), key (optional)
  plain="$1"
  k="$2"
  [ -z "$k" ] && k="$key"
  if [ -z "$k" ]; then
    printf '%s' "ERR:no key provided" >&2
    return 1
  fi

  # build 24-byte ASCII key: key + 16 ASCII '0'
  key24="$k"
  i=0
  while [ "$i" -lt 16 ]; do
    key24="${key24}0"
    i=$((i+1))
  done

  # compute padlen (PKCS#7 style for blocksize=8)
  len=$(printf '%s' "$plain" | wc -c)
  mod=$((len % 8))
  padlen=$((8 - mod))
  if [ "$mod" -eq 0 ]; then
    padlen=8
  fi

  tf_plain="$(mktemp -t getiptv_plain.XXXXXX 2>/dev/null || echo /tmp/getiptv_plain.$$)"
  printf '%s' "$plain" > "$tf_plain"
  awk -v n="$padlen" -v v="$padlen" 'BEGIN{ for(i=0;i<n;i++) printf "%c", v }' >> "$tf_plain"

  # convert key24 (ASCII) to hex
  keyhex="$(printf '%s' "$key24" | hexdump -v -e '/1 "%02x"')"

  # encrypt using openssl (3DES ECB)
  tf_out="$(mktemp -t getiptv_out.XXXXXX 2>/dev/null || echo /tmp/getiptv_out.$$)"
  if ! openssl enc -des-ede3 -nosalt -nopad -K "$keyhex" -in "$tf_plain" -out "$tf_out" 2>/dev/null; then
    rm -f "$tf_plain" "$tf_out"
    printf '%s' "ERR:openssl encrypt failed" >&2
    return 2
  fi

  hexdump -v -e '/1 "%02x"' "$tf_out"

  rm -f "$tf_plain" "$tf_out"
  return 0
}


############################
# 1. 获取 CTCGetAuthInfo
############################
get_ctc_token() {

    URL="$ITV_HOST/auth?UserID=${USERID}&Action=Login"

    PAGE=$(curl -s -L -A "$USERAGENT" "$URL" | tee $GOT_FILE/iptvlogin)

    CTC_TOKEN=$(echo "$PAGE"| sed -n "s/.*CTCGetAuthInfo('\([^']*\)').*/\1/p")

    if [ -z "$CTC_TOKEN" ]; then
        echolog "[-] 获取 CTCGetAuthInfo 失败"
        exit 1
    else
        echolog "当前 CTCGetAuthInfo 是 $CTC_TOKEN"
    fi
}

############################
# 2. 生成 Authenticator
############################
make_authenticator() {

    RAND=$(tr -dc 0-9 </dev/urandom | head -c8)

    SESSION_REF="${RAND}\$${CTC_TOKEN}\$${USERID}\$${STBID}\$${IP}\$${MAC}\$\$CTC"
    #echo "$SESSION_REF"

    AUTHENTICATOR=$(des3_encrypt "$SESSION_REF" "$KEY")
    
    if [ -z "$AUTHENTICATOR" ]; then
        echolog "[-] DES3 加密失败"
        exit 1
    else
        echolog "当前加密生成的 AUTHENTICATOR 是 $AUTHENTICATOR "
    fi
    
}

############################
# 3. 获取 usertoken 作为cookie
############################
get_usertoken() {
    RESP=$(curl -s \
        -c $GOT_FILE/usertoken.cookie \
        -A "$USERAGENT" \
        -d "UserID=${USERID}" \
        -d "Authenticator=${AUTHENTICATOR}" \
        -d "AccessMethod=dhcp" \
        -d "AccessUserName=${USERID}@vod" \
        "$ITV_HOST/uploadAuthInfo" | tee $GOT_FILE/iptvuploadAuthInfo)

    USERTOKEN=$(echo "$RESP" | sed -n "s/.*UserToken','\([^']*\)'.*/\1/p")

    if [ -z "$USERTOKEN" ]; then
        echo "[-] USERTOKEN 获取失败"
        exit 1
    else
        echolog "当前 usertoken 是 $USERTOKEN"
    fi
}

############################
# 4、得到 JSESSIONID 
############################
get_session() {
    RESP=$(curl -s \
        -A "$USERAGENT" \
        -b "UserToken=$USERTOKEN" \
        "$ITV_HOST/getServiceList" | tee $GOT_FILE/getServiceList)
    
    UserGroupNMBURL=$(echo "$RESP" | sed -n "s/.*location='\(http:\/\/[^\']*\)'.*/\1/p")

    if [ -z "$UserGroupNMBURL" ]; then
        echolog "[-] UserGroupNMB 链接获取失败"
        exit 1	
    else
        echolog "当前 UserGroupNMB 链接是 $UserGroupNMBURL"
    fi

    RESP=$(curl -s \
        -A "$USERAGENT" \
        "$UserGroupNMBURL" | tee $GOT_FILE/UserGroupNMB )
    
    loadbancedurl=$(echo "$RESP" | sed -n "s/.*location[[:space:]]*=[[:space:]]*'\([^']*\)'.*/\1/p")

    if [ -z "$loadbancedurl" ]; then
        echolog "[-] loadbancedurl 获取失败"
        exit 1	
    else
        echolog "当前 loadbancedurl 是 $loadbancedurl"
    fi	
    
    # 获取新负载均衡服务器地址
    AUTHHOST=$(echo "$loadbancedurl" | cut -d/ -f1-3)
    
    # 获得cookie,从响应头获取
    JSESSIONID=$(curl -s -A "$USERAGENT" -D - "$loadbancedurl" -o $GOT_FILE/loadbancedurl \
        | grep -i '^Set-Cookie:' \
        | awk '{print $2}' \
        | cut -d';' -f1)
    
    echo "$JSESSIONID" > $GOT_FILE/JSESSIONID
    
    if [ -z "$JSESSIONID" ]; then
        echolog "[-] JSESSIONID 获取失败"
        exit 1	
    else
        echolog "当前 JSESSIONID 是 $JSESSIONID"
    fi	
    
    post_data=$(cat "$GOT_FILE/loadbancedurl" \
        | grep -i '<input' \
        | grep -i 'type="hidden"' \
        | sed -n 's/.*name="\([^"]*\)".*value="\?\([^">]\+\)"\?.*/\1=\2/p' \
        | tr '\n' '&' | sed 's/&$//')

}

############################
# 5. 获取组播频道列表
############################
get_channel_list() {
    #先进行验证直播源获取主要url为funcportalauth、frameset_judger
    RESP=$(curl -s \
        -A "$USERAGENT" \
        -b "$JSESSIONID" \
        -d "$post_data" \
        -d "stbtype=B860AV1.1" \
        "$AUTHHOST/iptvepg/function/funcportalauth.jsp" | tee $GOT_FILE/funcportalauth)	
    
    RESP=$(curl -s \
        -A "$USERAGENT" \
        -b "$JSESSIONID" \
        -d "picturetype=1,3,5" \
        "$AUTHHOST/iptvepg/function/frameset_judger.jsp" | tee $GOT_FILE/frameset_judger)
        
    post_builder_data=$(cat "$GOT_FILE/frameset_judger" \
        | grep -i '<input' \
        | grep -i 'type="hidden"' \
        | sed -n 's/.*name="\([^"]*\)".*value="\?\([^">]\+\)"\?.*/\1=\2/p' \
        | tr '\n' '&' | sed 's/&$//')
    
    echolog "[+] 获取组播频道列表..."
    # 获取节目列表,下面参数不能少
    PAGE=$(curl -s \
        -b "$JSESSIONID" \
        -A "$USERAGENT" \
        -d "$post_builder_data" \
        -d "hdmistatus=""" \
        "$AUTHHOST/iptvepg/function/frameset_builder.jsp" | tee $GOT_FILE/iptvlist)	

    if [ -z "$PAGE" ]; then
        echolog "[-] 未获取到频道列表"
        exit 1
    else
        echolog "已获取到频道列表,网页保存在$GOT_FILE/iptvlist"
    fi

    TXT="$GOT_FILE/hitv.txt"
    M3U="$GOT_FILE/hitv.m3u"

    echo "#EXTM3U url-tvg=\"http://e.erw.cc/e.xml\"" > "$M3U"
    echo "" > "$TXT"
    echo "" > "$GOT_FILE/iptvlist.sort"
    
    cat $GOT_FILE/iptvlist | grep -o 'ChannelID="[^"]*".*ChannelFccAgentAddr="[^"]*"' | \
    while read -r line; do
        CID=$(echo "$line" | sed -n 's/.*ChannelID="\([^"]*\)".*/\1/p')
        NAME=$(echo "$line" | sed -n 's/.*ChannelName="\([^"]*\)".*/\1/p')
        RTP=$(echo "$line" | sed -n 's/.*ChannelURL="igmp:\/\/\([^"]*\)".*/\1/p')
        BACK=$(echo "$line" | sed -n 's/.*TimeShiftURL="\([^"]*\)".*/\1/p')
        FFC=$(echo "$line" | sed -n 's/.*ChannelFCCServerAddr="\([^"]*\)".*/\1/p')

        if echo "$NAME" | grep -iqE 'hd|4k'; then
            # 进行时移链接转换
            BACK=$(echo "$BACK" | sed "s#^rtsp://#${ROUTEIP}/rtsp/#")	
            # 写入临时排序文件:用 | 分隔字段
            echo "${CID}|${NAME}|${RTP}|${BACK}|${FFC}" >> "$GOT_FILE/iptvlist.sort"
        fi
    done

    sort -n -t'|' -k 1 "$GOT_FILE/iptvlist.sort" | while IFS='|' read -r CID NAME RTP BACK FFC; do
        echo -e "${NAME},${ROUTEIP}/rtp/${RTP}?fcc=${FFC}\n${NAME},${BACK}" >> "$TXT"
        echo "#EXTINF:-1 tvg-id="\"${CID}\"" tvg-name="\"${NAME}\"" catchup="\"default\"" catchup-source="\"${BACK}\&playseek={utc:YmdHMS\}-{utcend:YmdHMS}\"" tvg-logo="\"\"" group-title="\"ITV\"",${NAME}" >> "$M3U"		
        echo "${ROUTEIP}/rtp/${RTP}?fcc=${FFC}" >> "$M3U"

    done
    
    cp -f "$M3U" /www
    cp -f "$TXT" /www
    chmod 644 /www/hitv.m3u
    chmod 644 /www/hitv.txt
    echolog "IPTV 播放列表 生成完毕。$TXT $M3U"

}

############################
# 主流程
############################
mkdir -p "$GOT_FILE"
echo "" >> /usr/share/myfile/iptv.log
get_iptvip
get_ctc_token
make_authenticator
get_usertoken
get_session
get_channel_list

该脚本只获取了含有HD和4K字样的频道名称,各地不一样注意修改。里面的 palyseek={utc:YmdHMS}-{utcend:YmdHMS} 及其他情况根据实际情况修改。将该段shell,utf-8编码,保存为 iptv.sh ,放到 /etc/init.d/ 文件夹内,给755 权限,shell终端执行/etc/init.d/iptv.sh即可自动生成IPTV M3U文件,还生成了文本格式cctv1,http://192.168.1.1/rtp/223... 。M3U文件放入到了/www/hitv.m3u,供其他终端获取,比如tivimate可以导入的M3U文件地址就是http://192.168.1.1/hitv.m3u

还得加个hotplug 热插拔事件脚本,一旦iptv口重启或启动就自动生成新的m3u播放列表。重启后IPTV口的ip变了,rtsp单播鉴权信息就失效,需要重新生成。上一篇介绍过hotplug 热插拔事件脚本,稍微改下就可以用,就不重复发了。

几天折腾下来,终于圆满达成了目标。非专业人士,这2篇关于IPTV的文章如有错谬,敬请谅解。

技术不断升级,请注意文章时效性。
本站文章,欢迎转发。转载请注明出处:https://www.bandwh.com/net/2637.html

(4)

BandWh.com 折腾之路●一起折腾

上一篇 2026年1月21日 08:58
下一篇 2025年7月18日 11:49
瓦工BIGGERBOX-20-1024

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

请文明评论!

评论列表(2条)

  • 明
    2026年2月8日 00:46

    我的ITV密码只有6位数,现在一直卡在获取USERTOKEN这一步,应该是加密过程有影响,还有MAC地址应该是输入大写的还是小写的,有啥好点的方法不

    • 明
      2026年2月8日 07:52

      @明解决了,补位那边就有笑哭