Skip to content

Commit e086401

Browse files
committed
Update pvcep_rules.js
1 parent c0375d0 commit e086401

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

Picviewer CE+/pvcep_rules.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,58 @@ var siteInfo = [
838838
}
839839
}
840840
},
841+
{
842+
name: "Twitch",
843+
url: /^https:\/\/(www\.twitch\.tv\/|www\.reddit\.com\/r\/TwitchClips\/)/,
844+
xhr: {
845+
url: function(a, p, xhr) {
846+
if (!a) return;
847+
if (!/twitch\.tv/.test(a.href)) return;
848+
let m = a.href.match(/(\/clip\/|clips\.twitch\.tv\/)([^?]{1,})/);
849+
if (m) {
850+
var slug = m[2];
851+
var operationNameClip = "VideoAccessToken_Clip";
852+
var operationNameLiveOrVOD = "PlaybackAccessToken";
853+
var sha256HashClip = "36b89d2507fce29e5ca551df756d27c1cfe079e2609642b4390aa4c35796eb11";
854+
var sha256HashLiveOrVOD = "0828119ded1c13477966434e15800ff57ddacf13ba1911c129dc2200705b0712";
855+
return `https://gql.twitch.tv/gql#p{{"operationName":"${operationNameClip}","variables":{"slug":"${slug}"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"${sha256HashClip}"}}}}`;
856+
} else {
857+
m = a.href.match(/(?:m\.|www\.)?twitch\.tv\/(?:(?!directory|downloads|jobs|store|twitchartists|turbo|privacy)(\w+)$|(?:\w+\/)?videos\/(\d+))/);
858+
if (m) {
859+
xhr.m = m;
860+
return `https://gql.twitch.tv/gql#p{{"operationName":"PlaybackAccessToken_Template","query":"query PlaybackAccessToken_Template($login: String!, $isLive: Boolean!, $vodID: ID!, $isVod: Boolean!, $playerType: String!, $platform: String!) { streamPlaybackAccessToken(channelName: $login, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isLive) { value signature authorization { isForbidden forbiddenReasonCode } __typename } videoPlaybackAccessToken(id: $vodID, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isVod) { value signature __typename }}","variables":{"isLive":${m[1]?'true':'false'},"login":"${m[1]||''}","isVod":true,"vodID":"${m[2]||''}","playerType":"site","platform":"web"}}}`;
861+
}
862+
}
863+
},
864+
headers: function(url, xhr, getCookie) {
865+
return {"Client-ID":"kimne78kx3ncx6brgo4mv6wki5h1ko", "X-Device-Id": getCookie('unique_id') || getCookie('unique_id_durable') || 'd56e8463c57c7cd7'}
866+
},
867+
cacheNum: 20,
868+
query: function(html, doc, u, xhr) {
869+
try {
870+
let r = JSON.parse(html);
871+
if (r.data.clip) {
872+
let signature = r.data.clip.playbackAccessToken.signature;
873+
let token = r.data.clip.playbackAccessToken.value;
874+
let t = JSON.parse(token);
875+
let clip_uri = r.data.clip.videoQualities[0].sourceURL;
876+
let fullsizeUrl = clip_uri + '?sig=' + signature + '&token=' + encodeURIComponent(token);
877+
878+
return {url: ["video:" + fullsizeUrl], cap: ""};
879+
} else {
880+
let tokens = r.data.streamPlaybackAccessToken || r.data.videoPlaybackAccessToken;
881+
if (!tokens) return;
882+
let hex = ['A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
883+
let url = xhr.m[1] ? 'api/channel/hls': 'vod';
884+
let p = Math.floor(999999 * Math.random());
885+
let id = '';
886+
for (let i = 0; i < 32; i++) id += hex[Math.floor(Math.random() * 16)];
887+
return `video:https://usher.ttvnw.net/${url}/${xhr.m[1]||xhr.m[2]}.m3u8?acmb=eyJBcHBWZXJzaW9uIjoiYjlhNjU4ZWMtMTcyMS00Y2FjLThkMjgtZjk0NmJmY2E3YzUwIn0%3D&allow_source=true&p=${p}&platform=web&play_session_id=${id}&sig=${tokens.signature}&supported_codecs=av1,h264&token=${encodeURIComponent(tokens.value)}&transcode_mode=cbr_v1`;
888+
}
889+
} catch { }
890+
}
891+
}
892+
},
841893
{
842894
name: "Rule34hentai",
843895
url: /rule34hentai\.net/,
@@ -1368,7 +1420,7 @@ var siteInfo = [
13681420
const images = items0.image_versions2;
13691421
const carousel = items0.carousel_media;
13701422
if (videos) {
1371-
const videoUrl = videos[0].url + '.video';
1423+
const videoUrl = "video:" + videos[0].url;
13721424
let videoAudioSubtitlesUrl = videoUrl;
13731425
const caption = (items0.caption ? items0.caption.text : (items0.accessibility_caption ? items0.accessibility_caption : items0.user.full_name));
13741426
return {url: [videoUrl], cap: caption};

0 commit comments

Comments
 (0)