diff --git a/src/extractor/Fastream.ts b/src/extractor/Fastream.ts index 8831085..544251a 100644 --- a/src/extractor/Fastream.ts +++ b/src/extractor/Fastream.ts @@ -1,5 +1,6 @@ +import bytes from 'bytes'; import { Context, CountryCode, Format, UrlResult } from '../types'; -import { buildMediaFlowProxyExtractorStreamUrl, Fetcher, guessHeightFromPlaylist, supportsMediaFlowProxy } from '../utils'; +import { buildMediaFlowProxyExtractorStreamUrl, Fetcher, supportsMediaFlowProxy } from '../utils'; import { Extractor } from './Extractor'; export class Fastream extends Extractor { @@ -23,9 +24,19 @@ export class Fastream extends Extractor { return null !== url.host.match(/fastream/) && supportsMediaFlowProxy(ctx); } + public override normalize(url: URL): URL { + return new URL(url.href.replace('/e/', '/embed-').replace('/d/', '/embed-')); + } + protected async extractInternal(ctx: Context, url: URL, countryCode: CountryCode): Promise { const playlistUrl = await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'Fastream', url); + const downloadUrl = new URL(url.href.replace('/embed-', '/d/')); + const html = await this.fetcher.text(ctx, downloadUrl); + + const heightAndSizeMatch = html.match(/\d{3,}x(\d{3,}), ([\d.]+ ?[GM]B)/) as string[]; + const titleMatch = html.match(/>Download (.*?) + + + + Fastream + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+ + +
+ + Sign Up +
+
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + +
Download black.mirror.s01e01.lat.720p.mp4
UHD quality1920x1080, 1.0 GB
HD quality1280x720, 396.8 MB
Normal quality852x480, 210.1 MB
Low quality640x360, 104.0 MB
+ +
+ + + + + + +
+ + + diff --git a/src/extractor/__fixtures__/Fastream/https:mediaflow-proxy.test-a27e0ed17a89171a46626397d1f1adf9 b/src/extractor/__fixtures__/Fastream/https:mediaflow-proxy.test-a27e0ed17a89171a46626397d1f1adf9 deleted file mode 100644 index a93a49f..0000000 --- a/src/extractor/__fixtures__/Fastream/https:mediaflow-proxy.test-a27e0ed17a89171a46626397d1f1adf9 +++ /dev/null @@ -1,13 +0,0 @@ -#EXTM3U -#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=318390,RESOLUTION=640x360,FRAME-RATE=25.000,CODECS="avc1.64001e,mp4a.40.2" -https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_l%2Findex-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0 -#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=648989,RESOLUTION=852x480,FRAME-RATE=25.000,CODECS="avc1.64001e,mp4a.40.2" -https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_n%2Findex-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0 -#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1231528,RESOLUTION=1280x720,FRAME-RATE=25.000,CODECS="avc1.64001f,mp4a.40.2" -https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_h%2Findex-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0 -#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3193889,RESOLUTION=1920x1080,FRAME-RATE=25.000,CODECS="avc1.42001e,mp4a.40.2" -https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_x%2Findex-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=21129,RESOLUTION=640x360,CODECS="avc1.64001e",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_l%2Fiframes-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0" -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=37640,RESOLUTION=852x480,CODECS="avc1.64001e",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_n%2Fiframes-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0" -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=63209,RESOLUTION=1280x720,CODECS="avc1.64001f",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_h%2Fiframes-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0" -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=693070,RESOLUTION=1920x1080,CODECS="avc1.42001e",URI="https://mediaflow-proxy.test/proxy/hls/manifest.m3u8?api_password=asdfg&h_user-agent=Mozilla%2F5.0+%28X11%3B+Linux+x86_64%3B+rv%3A138.0%29+Gecko%2F20100101+Firefox%2F138.0&h_Accept=%2A%2F%2A&h_Connection=keep-alive&h_Accept-Language=en-US%2Cen%3Bq%3D0.5&h_referer=https%3A%2F%2Ffastream.to%2F&h_origin=https%3A%2F%2Ffastream.to&d=https%3A%2F%2Fs28.fastream.to%2Fhls2%2F09%2F00024%2F3aooif4ozt10_x%2Fiframes-v1-a1.m3u8%3Ft%3Dnw6_aeN6pDROuXsJQwyrJVm3qHKFedVfbTNj5LgXH-4%26s%3D1752863379%26e%3D43200%26v%3D1058373%26i%3D0.3%26sp%3D0" diff --git a/src/extractor/__snapshots__/Fastream.test.ts.snap b/src/extractor/__snapshots__/Fastream.test.ts.snap index f542227..0ff4476 100644 --- a/src/extractor/__snapshots__/Fastream.test.ts.snap +++ b/src/extractor/__snapshots__/Fastream.test.ts.snap @@ -6,10 +6,12 @@ exports[`Fastream fastream.to embed 1`] = ` "format": "hls", "label": "Fastream (via MediaFlow Proxy)", "meta": { + "bytes": 1073741824, "countryCodes": [ "es", ], "height": 1080, + "title": "black.mirror.s01e01.lat.720p.mp4", }, "sourceId": "fastream_es", "ttl": 0,