我爱学习
// ==UserScript==
// @name 知识视频
// @namespace http://tampermonkey.net/
// @version 2025-08-29
// @description 我爱学习
// @author cw2012
// @match http*://wx.zsxq.com/group/*/topic/*
// @icon https://wx.zsxq.com/assets_dweb/images/favicon_32.ico
// @run-at document-idle
// @grant GM_xmlhttpRequest
// @grant GM_download
// @connect videos.zsxq.com
// @connect api.zsxq.com
// @connect auth.zsxq.com
// @license MIT
// ==/UserScript==
let topic = {};
let video = {};
setTimeout(function() {
'use strict';
topic.id = location.href.split('/')[6];
getTopicInfo();
}, 4000);
function getTopicInfo(){
const url = `https://api.zsxq.com/v2/topics/${topic.id}/info`;
GM_xmlhttpRequest({
url: url,
method: 'get',
onload: res => {
res = res.responseText;
res = JSON.parse(res);
if(res.succeeded){
res = res.resp_data.topic.talk;
topic.title = res.text;
if(res.hasOwnProperty('video')){
topic.videoId = res.video.video_id;
getVideoM3u8();
}else{
console.log('本页面没有视频');
}
}else{
alert('帖子信息获取失败');
}
}
});
}
function getVideoM3u8(){
GM_xmlhttpRequest({
url: `https://api.zsxq.com/v2/videos/${topic.videoId}/url`,
method: 'get',
onload: res => {
res = res.responseText;
res = JSON.parse(res);
if(res.succeeded){
topic.videoUrl = res.resp_data.url;
downloadM3u8AndKey();
}else{
alert('视频信息获取失败');
}
}
});
}
function downloadM3u8AndKey(){
let regexp = /([\d\w\-]+\.ts)/g;
GM_xmlhttpRequest({
url: topic.videoUrl,
method: 'get',
onload: res => {
res = res.responseText;
let tmp = res.replace(regexp, "https://videos.zsxq.com/$1");
regexp = /#EXT-X-KEY:[^,]+,URI="([^"]+)"/;
const match = tmp.match(regexp);
if(match && match[1]){
const originalUri = match[1];
downlowdKey(originalUri);
downloadM3u8(tmp);
}
}
});
}
function downlowdKey(keyUrl){
GM_xmlhttpRequest({
method: "GET",
url: keyUrl,
timeout: 35_000,
responseType:'blob',
onload: function(res){
const fileBlob = res.response;
let keyName = `${topic.title}.bin`;
downloadFileByBlob(fileBlob, keyName)
},
onerror: ()=>{
console.error('下载出错\t' + keyUrl)
}
});
}
function downloadM3u8(tmp){
const newUri = `${topic.title}.bin`;
tmp = tmp.replace(/(#EXT-X-KEY:[^,]+,URI=")[^"]+(")/g, `$1${newUri}$2`);
// 创建文本类型的Blob(指定MIME类型为text/plain)
const blob = new Blob([tmp], { type: 'text/plain' });
downloadFileByBlob(blob, topic.title + '.m3u8');
console.log(tmp);
}
// 利用blob下载文件
function downloadFileByBlob(blobContent, filename) {
const blobUrl = URL.createObjectURL(blobContent)
const eleLink = document.createElement('a')
eleLink.download = filename
eleLink.style.display = 'none'
eleLink.href = blobUrl
eleLink.click();
}