[web.rest] 解析bilibili分享链接,获取视频的MP4直链

Mr_MAO 15天前 336


//2025/12/26更新:按照官方公众号的文章指导,用AI更换了一个有现代感的界面 :)
import win.ui;
import win.ui.simpleWindow;
import win.clip;
import web.rest.jsonClient;
import process;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="Bilibili 视频直链解析工具";right=799;bottom=549;bgcolor=0xFFFFFF;border="none")
winform.add(
bk={cls="bkplus";left=0;top=0;right=800;bottom=48;bgcolor=0xF088B1;dl=1;dr=1;dt=1;z=1};
btnClipboard={cls="plus";text="从剪贴板读取并解析";left=588;top=488;right=776;bottom=528;align="left";bgcolor=0xFFFFFF;border={color=0xFFE9E9E9;radius=20;width=1};db=1;dr=1;font=LOGFONT(h=-14);iconStyle={align="left";font=LOGFONT(h=-15;name='FontAwesome');padding={left=15}};iconText='\uF0EA';notify=1;textPadding={left=40};z=10};
btnCopy={cls="plus";text="复制直链";left=184;top=488;right=320;bottom=528;align="left";bgcolor=0xFFFFFF;border={color=0xFFE9E9E9;radius=20;width=1};db=1;disabled=1;dl=1;font=LOGFONT(h=-14);iconStyle={align="left";font=LOGFONT(h=-15;name='FontAwesome');padding={left=15}};iconText='\uF0C5';notify=1;textPadding={left=40};z=8};
btnOpen={cls="plus";text="浏览器打开";left=24;top=488;right=168;bottom=528;align="left";bgcolor=0xFFFFFF;border={color=0xFFE9E9E9;radius=20;width=1};db=1;disabled=1;dl=1;font=LOGFONT(h=-14);iconStyle={align="left";font=LOGFONT(h=-15;name='FontAwesome');padding={left=15}};iconText='\uF0AC';notify=1;textPadding={left=40};z=9};
btnParse={cls="plus";text="立即解析";left=448;top=488;right=576;bottom=528;align="left";bgcolor=0xB079FF;border={radius=20};color=0xFFFFFF;db=1;dr=1;font=LOGFONT(h=-14;weight=600);iconStyle={align="left";font=LOGFONT(h=-15;name='FontAwesome');padding={left=15}};iconText='\uF002';notify=1;textPadding={left=40};z=3};
caption={cls="bkplus";text="Bilibili 视频直链解析工具";left=48;top=13;right=304;bottom=33;color=0xFFFFFF;dl=1;dt=1;font=LOGFONT(h=-16;weight=600);z=2};
editInput={cls="edit";left=32;top=88;right=768;bottom=152;autohscroll=false;dl=1;dr=1;dt=1;edge=1;font=LOGFONT(h=-14);hidesel=1;multiline=1;z=5};
editOutput={cls="edit";left=32;top=184;right=768;bottom=464;autohscroll=false;bgcolor=0xFFFFFF;db=1;dl=1;dr=1;dt=1;edge=1;font=LOGFONT(h=-13);multiline=1;readonly=1;vscroll=1;z=7};
icon={cls="bkplus";text='\uF019';left=14;top=10;right=41;bottom=36;color=0xFFFFFF;dl=1;dt=1;font=LOGFONT(h=-20;name='FontAwesome');z=4};
static={cls="plus";text="请输入 Bilibili 视频链接 (支持 BV 号/短链接/网页链接)";left=32;top=64;right=448;bottom=84;align="left";color=0x5A5A5A;dl=1;dt=1;font=LOGFONT(h=-13);z=6};
static2={cls="plus";text="解析状态及结果展示";left=32;top=160;right=448;bottom=180;align="left";color=0x5A5A5A;dl=1;dt=1;font=LOGFONT(h=-13);z=11}
)
/*}}*/

var simpleWindow = win.ui.simpleWindow(winform);

var btnSkin = {
    background={
        default=0xFFFB7299;
        hover=0xFFFF8EAB;
        active=0xFFD45D7D;
        disabled=0xFFCCCCCC;
    };
    color={
        default=0xFFFFFFFF;
    }
}

var btnOutlineSkin = {
    background={
        default=0xFFFFFFFF;
        hover=0xFFF4F4F4;
        active=0xFFEAEAEA;
        disabled=0xFFFFFFFF;
    };
    color={
        default=0xFFFB7299;
        disabled=0xFFAAAAAA;
    };
    border={
        default={color=0xFFFB7299;width=1;radius=20};
        disabled={color=0xFFAAAAAA;width=1;radius=20};
    }
}

winform.btnParse.skin(btnSkin);
winform.btnOpen.skin(btnOutlineSkin);
winform.btnCopy.skin(btnOutlineSkin);
winform.btnClipboard.skin(btnOutlineSkin);

var lastVideoUrl = "";

winform.updateResult = function(videoUrl, title){
    if(videoUrl){
        lastVideoUrl = videoUrl;
        winform.btnCopy.disabled = false;
        winform.btnOpen.disabled = false;

        winform.editOutput.text = "";
        winform.editOutput.print("【视频标题】:《" ++ title ++ "》");
        winform.editOutput.print('\r\n解析成功!已获得 MP4 直链地址:');
        winform.editOutput.print("------------------------------------------------------------");
        winform.editOutput.print(videoUrl);
        winform.editOutput.print("------------------------------------------------------------");
        winform.editOutput.print("note: 解析完成!已激活 [浏览器打开] / [复制直链] 按钮↙。");
    }
    else {
        winform.btnCopy.disabled = true;
        winform.btnOpen.disabled = true;
    }
}

// 解析逻辑
var runParser = function(text){
    if(!text || #text == 0){
        winform.msgboxErr("请输入链接内容!");
        return;
    }

    var bvid = string.match(text, "(BV\w+)");
    if(!bvid){
        // 尝试解析短链接
        if(string.find(text, "b23.tv")){
            winform.editOutput.text = "正在解析短链接,请稍候...";
        } else {
            winform.msgboxErr("未在输入内容中匹配到 BV 号!");
            return;
        }
    }

    lastVideoUrl = "";
    winform.btnCopy.disabled = true;
    winform.btnOpen.disabled = true;
    winform.editOutput.text = "正在初始化解析任务...\r\n";

    // 动画状态
    winform.btnParse.disabledText = {'\uF254';'\uF251';'\uF252';'\uF253';'\uF250'};

    thread.invoke( 
        function(winform, text, bvid){
            import web.rest.jsonClient;
            var http = web.rest.jsonClient();
            http.addHeaders = {
                ["Referer"] = "https://www.bilibili.com/video/" ++ bvid;
                ["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36";
            }

            // 如果只有短链接没有 BVID,先获取真实地址
            if(!bvid){
                var shortUrl = string.match(text, "https\://b23\.tv/\w+");
                if(shortUrl){
                    http.sendRawData = false;
                    http.get(shortUrl);
                    var realUrl = http.lastResponseString(); 
                    // 实际上 web.rest 会自动重定向,此处简化逻辑,重提 BVID
                    bvid = string.match(http.lastRequestUrl || "", "(BV\w+)");
                }
            }

            if(!bvid){
                winform.btnParse.disabledText = null;
                winform.editOutput.print("解析失败:无法从链接中提取 BVID");
                return;
            }

            winform.editOutput.print("正在获取视频信息: " + bvid);

            // 1. 获取 CID
            var viewData = http.api("https://api.bilibili.com/x/web-interface/view").get( bvid = bvid );
            if(!viewData ? viewData.code != 0){
                winform.editOutput.print("错误: " + (viewData ? viewData.message : "网络请求失败"));
                winform.btnParse.disabledText = null;
                return;
            }

            var aid = viewData.data.aid;
            var cid = viewData.data.cid;
            var title = viewData.data.title;

            // 2. 获取播放地址 (使用 HTML5 平台参数以获取 MP4 直链)
            var playData = http.api("https://api.bilibili.com/x/player/playurl").get(
                avid = aid; bvid = bvid; cid = cid;
                qn = 16; fnval = 0; fnver = 0; platform = "html5"; high_quality = 1
            );

            winform.btnParse.disabledText = null;

            if(playData ? playData.code == 0){
                var durl = playData.data ? playData.data.durl;
                if(durl && #durl > 0){
                    winform.updateResult(durl[1].url, title);
                } else {
                    winform.editOutput.print("解析失败:B站未返回直链数据(可能需要登录或由于版权限制)");
                }
            } else {
                winform.editOutput.print("接口返回错误: " + (playData ? playData.message : "未知错误"));
            }
        }, winform, text, bvid
    )
}

// 绑定事件
winform.btnParse.oncommand = function(id,event){
    runParser(winform.editInput.text);
}

winform.btnCopy.oncommand = function(id,event){
    if(#lastVideoUrl > 0){
        win.clip.write(lastVideoUrl);
        winform.msgbox("直链已成功复制到剪贴板!", "成功");
    }
}

winform.btnOpen.oncommand = function(id,event){
    if(#lastVideoUrl > 0) process.execute(lastVideoUrl);
}

winform.btnClipboard.oncommand = function(id,event){
    var clipText = win.clip.read();
    if(clipText){
        winform.editInput.text = clipText;
        runParser(clipText);
    }
}

// 初始默认值
winform.editInput.text = "https://www.bilibili.com/video/BV17yH8znEpx";

winform.show();
win.loopMessage();
最新回复 (8)
  • netfox 14天前
    2 2
    老阿姨值得顶上去
  • 光庆 14天前
    0 3
    图很给力。涨知势了。
  • Mr_MAO 14天前
    1 4

    代码没什么营养,但配图一定要能提神!😊

  • mfk 14天前
    0 5
  • netfox 14天前
    0 6
    Mr_MAO 代码很普通没什么营养,但配图一定要能提神!😊
    前晚的快手直播才提神🥱
  • shzhbook 12天前
    0 7
    顶一下大佬
  • retn 10天前
    0 8
    建议出一个系列的,抖音,虎牙,斗鱼
  • cyzn_lfss 5天前
    0 9
    感谢大佬源码分享
返回