1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| export async function onRequest(context) { let params = context.params let vid = params.vid let is_bvid if(vid.startsWith('BV')){ is_bvid=true } else if(vid.startsWith('av') || vid.startsWith('AV')) { is_bvid=false vid = vid.slice(2) } else { return new Response(`Uknown video id type for ${vid}, only support [av,AV,BV].`) }
let qual = { '360': 16, '480': 32, '720': 64, '720+': 74, '1080': 80, '1080+': 112, '4k': 120, 'hdr': 125, 'dolby': 126, '8k': 127 }[params.qual] let page_id = Number.parseInt(params.p) if (Number.isNaN(page_id)) { return new Response(`pageNum ${page_id} is not a number!`) } if (qual > 80 || qual == undefined){ return new Response("quality not supported,only support [360,480,720,720+,1080]!") } let video_info = await (await fetch(buildBiliReq(`https://api.bilibili.com/x/player/pagelist?${is_bvid ? 'bvid' : 'aid'}=${vid}`))).json() if (video_info.code != 0) { return new Response(`BiliApi error: returned code ${video_info.code},message: ${video_info.message}`) } let page = video_info.data[page_id] if (page == undefined) { return new Response(`pageNum out of range: requested p${page_id+1} but only have p${video_info.data.length}!`) } let cid = page.cid let playurl_info = await (await fetch(buildBiliReq(`https://api.bilibili.com/x/player/playurl?${is_bvid ? 'bvid' : 'avid'}=${vid}&cid=${cid}&qn=${qual}&fnval=1&fnver=0&platform=pc`))).json() if (playurl_info.code != 0) { return new Response(`BiliApi error: getstream returned code ${playurl_info.code},message: ${playurl_info.message}`) } let video_url = playurl_info.data.durl[0].url let video_file_name = `${vid}-P${page_id+1}-${page.part}-CID${cid}_${page.dimension.width}x${page.dimension.height}.mp4` let video_response = await fetch(buildBiliReq(video_url,{'Range':context.request.headers.Range})) let fin_video_response = new Response(video_response.body,video_response) fin_video_response.headers.set('Access-Control-Allow-Origin', '*') fin_video_response.headers.set('X-Bili-CID', cid) fin_video_response.headers.set('X-Bili-VID', vid) fin_video_response.headers.set('X-Bili-VID-URL', video_url) fin_video_response.headers.set('Content-Disposition', `inline; filename="${video_file_name}"`) fin_video_response.headers.set('set-cookie', "The_Cutest_Miko_Chan_In_The_World=Reimu Hakurei!;")
return fin_video_response }
function buildBiliReq(url,customHeaders) { return new Request(url, { headers:Object.assign({ 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-language': 'zh-CN, zh', 'cache-control': 'no-cache', 'dnt': '1', 'pragma': 'no-cache', 'sec-ch-ua': '" Not A;Brand"v = "99", "Chromium"v = "96", "Microsoft Edge"v = "96"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Linux"', 'sec-fetch-dest': 'document', 'sec-fetch-mode': 'navigate', 'sec-fetch-site': 'none', 'sec-fetch-user': '?1', 'Referer':'https://www.bilibili.com/', 'Cookie': '换成自己小号的cookie', 'User-Agent': 'Mozilla/5.0 (X11; Linux) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62', },customHeaders) }); }
|