fix(extractor): handle Fsst with single file result

This commit is contained in:
WebStreamr 2025-06-18 09:33:00 +00:00
parent 9fcc1c60d4
commit 6c7993cdba
No known key found for this signature in database
4 changed files with 223 additions and 3 deletions

View file

@ -17,4 +17,8 @@ describe('Fsst', () => {
test('Dead City', async () => {
expect(await extractorRegistry.handle(ctx, new URL('https://fsst.online/embed/901994/'), CountryCode.de)).toMatchSnapshot();
});
test('How to Train Your Dragon', async () => {
expect(await extractorRegistry.handle(ctx, new URL('https://fsst.online/embed/902668/'), CountryCode.de)).toMatchSnapshot();
});
});

View file

@ -29,15 +29,17 @@ export class Fsst extends Extractor {
const filesMatch = html.match(/file:"(.*)"/) as string[];
return (filesMatch[1] as string).split(',').map((fileString, index) => {
const heightAndUrlMatch = fileString.match(/\[([\d]+)p\](.*)/) as string[];
const heightAndUrlMatch = fileString.match(/\[?([\d]*)p?]?(.*)/) as string[];
const fileHref = heightAndUrlMatch[2] as string;
const heightFromFileHrefMatch = fileHref.match(/([\d]+)p/) as string[];
return {
url: new URL(heightAndUrlMatch[2] as string),
url: new URL(fileHref),
label: this.label,
sourceId: `${this.id}_${countryCode}_${index}`,
meta: {
countryCode,
height: parseInt(heightAndUrlMatch[1] as string),
height: parseInt(heightAndUrlMatch[1] || heightFromFileHrefMatch[1] as string),
title,
},
};

View file

@ -0,0 +1,199 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>How To Train Your Dragon 2025.mp4</title>
<script src='/player/player-101224.js' type='text/javascript'></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-CFYS4N19SL"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-CFYS4N19SL', {cookie_flags: 'max-age=7200;secure;samesite=none'});
gtag('config', 'G-SZ2D21EHGZ', {cookie_flags: 'max-age=7200;secure;samesite=none'});
gtag('config', 'G-7F9RVQ2TM0', {cookie_flags: 'max-age=7200;secure;samesite=none'});
gtag('config', 'G-LZP7HENPSC', {cookie_flags: 'max-age=7200;secure;samesite=none'});
</script>
</head>
<body style="margin:0; padding:0; background:#000000; color:#ffffff">
<div id="Video902668" style="width:100%; height:100%;"></div>
<script>
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
SmartTV: function() {
return navigator.userAgent.match(/Apple TV|Tizen|Web0S|WebOS|TSBNetTV|PHILIPSTV|NETFLIX|BRAVIA|Opera TV Store|SmartTV|SmartTv/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.SmartTV() || isMobile.Windows());
}
};
if(isMobile.iOS()){
var player = new Playerjs({
id: 'Video902668',
subtitle: "",
poster: 'https://www.secvideo1.online/contents/videos_screenshots/902000/902668/preview.jpg',
file:"https://www.secvideo1.online/get_file/10/648fc9b266670e9ad6756a066a68a8db0b36868457/902000/902668/902668_360p.mp4/",
url: 'https://csst.online/videos/902668/how-to-train-your-dragon-2025-mp4/',
embed: "https://csst.online/embed/902668/",
default_quality: "360p",
preroll: "//4736.in/vpaid/?id=906", });
} else {
if(isMobile.Android()){
var player = new Playerjs({
id: 'Video902668',
subtitle: "",
poster: 'https://www.secvideo1.online/contents/videos_screenshots/902000/902668/preview.jpg',
file:"https://www.secvideo1.online/get_file/10/648fc9b266670e9ad6756a066a68a8db0b36868457/902000/902668/902668_360p.mp4/",
url: 'https://csst.online/videos/902668/how-to-train-your-dragon-2025-mp4/',
embed: "https://csst.online/embed/902668/",
default_quality: "360p",
preroll: "//4736.in/vpaid/?id=906", });
} else {
if(isMobile.SmartTV()){
var player = new Playerjs({
id: 'Video902668',
subtitle: "",
poster: 'https://www.secvideo1.online/contents/videos_screenshots/902000/902668/preview.jpg',
file:"https://www.secvideo1.online/get_file/10/648fc9b266670e9ad6756a066a68a8db0b36868457/902000/902668/902668_360p.mp4/",
url: 'https://csst.online/videos/902668/how-to-train-your-dragon-2025-mp4/',
embed: "https://csst.online/embed/902668/",
default_quality: "360p",
preroll: "//4736.in/vpaid/?id=906", });
} else {
var player = new Playerjs({
id: 'Video902668',
subtitle: "",
poster: 'https://www.secvideo1.online/contents/videos_screenshots/902000/902668/preview.jpg',
file:"https://www.secvideo1.online/get_file/10/648fc9b266670e9ad6756a066a68a8db0b36868457/902000/902668/902668_360p.mp4/",
url: 'https://csst.online/videos/902668/how-to-train-your-dragon-2025-mp4/',
embed: "https://csst.online/embed/902668/",
default_quality: "360p",
preroll: "//4736.in/vpaid/?id=906", });
}
}
}
</script>
<script>
function PlayerjsEvents(event,id,info){
if(event=="vast_url"){
url = info;
}
if(event=="inited"){
console.log("inited");
console.log(Math.round(player.api("time")));
window.parent.postMessage({
event: 'inited',
time: Math.round(player.api("time")),
}, '*');
}
if(event=="vast_Impression"){
console.log("Impression");
console.log(url);
yaCounter49597111.reachGoal('vast_impression', {Ads: url.split(/\/+/)[1]});
gtag('event', 'ADS_viewed', {
'send_to': 'G-LZP7HENPSC',
'event_category': 'Video',
'event_label': '28214',
});
gtag('event', 'Vast Impression', {
'send_to': 'G-7F9RVQ2TM0',
'event_category': 'Video',
'event_label': url.split(/\/+/)[1],
});
}
if(event=="start"){
console.log("started");
console.log(Math.round(player.api("time")));
yaCounter49597111.reachGoal('play');
gtag('event', 'Video_played', {
'send_to': 'G-LZP7HENPSC',
'event_category': 'Video',
'event_label': '28214',
});
gtag('event', 'Play', {
'send_to': 'G-SZ2D21EHGZ',
'event_category': 'Video',
'event_label': 'Play',
});
window.parent.postMessage({
event: 'started',
time: Math.round(player.api("time")),
}, '*');
}
if(event=="pause"){
console.log("paused");
console.log(Math.round(player.api("time")));
window.parent.postMessage({
event: 'paused',
time: Math.round(player.api("time")),
}, '*');
}
if(event=="end"){
console.log("ended");
console.log(Math.round(player.api("time")));
window.parent.postMessage({
event: 'ended',
time: Math.round(player.api("time")),
}, '*');
}
}
</script>
<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
(function (d, w, c) {
(w[c] = w[c] || []).push(function() {
try {
w.yaCounter49597111 = new Ya.Metrika2({
id:49597111,
clickmap:true,
trackLinks:true,
accurateTrackBounce:true
});
} catch(e) { }
});
var n = d.getElementsByTagName("script")[0],
s = d.createElement("script"),
f = function () { n.parentNode.insertBefore(s, n); };
s.type = "text/javascript";
s.async = true;
s.src = "https://cdn.jsdelivr.net/npm/yandex-metrica-watch/tag.js";
if (w.opera == "[object Opera]") {
d.addEventListener("DOMContentLoaded", f, false);
} else { f(); }
})(document, window, "yandex_metrika_callbacks2");
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/49597111" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
<!-- -->
<!-- 2 -->
<!-- -->
</body>
</html>

View file

@ -69,3 +69,18 @@ exports[`Fsst Dead City 1`] = `
},
]
`;
exports[`Fsst How to Train Your Dragon 1`] = `
[
{
"label": "Fsst",
"meta": {
"countryCode": "de",
"height": 360,
"title": "How To Train Your Dragon 2025.mp4",
},
"sourceId": "fsst_de_0",
"url": "https://www.secvideo1.online/get_file/10/648fc9b266670e9ad6756a066a68a8db0b36868457/902000/902668/902668_360p.mp4/",
},
]
`;