From 793a83e1398642c1c4aac3479b7139e7fc8c5117 Mon Sep 17 00:00:00 2001 From: dargy Date: Mon, 20 Jan 2025 21:56:45 -0600 Subject: [PATCH] feat: combining modes @Apocolypto https://github.com/okdargy/fxTikTok/issues/24#issuecomment-2601037039 --- .github/workflows/run-jest.yml | 5 +++++ README.md | 8 +++++++- src/index.ts | 27 ++++++++++++++++++--------- src/services/tiktok.ts | 3 ++- src/templates/index.ts | 2 +- src/util/responseHelper.ts | 16 ++++++---------- 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/.github/workflows/run-jest.yml b/.github/workflows/run-jest.yml index 08b3ed9..a8b6228 100644 --- a/.github/workflows/run-jest.yml +++ b/.github/workflows/run-jest.yml @@ -1,6 +1,11 @@ name: Run Unit Tests with Jest on: + push: + branches: + - main + - master + - hono-rewrite pull_request: branches: - main diff --git a/README.md b/README.md index 0dd2596..9c189e7 100644 --- a/README.md +++ b/README.md @@ -72,10 +72,16 @@ However, we want to give users the option to add it in case it brings additional TikTok supports H.265/HEVC (High Efficiency Video Coding) which offers significantly better quality at the same file size compared to H.264, at the cost of compatibility. By default, we use H.264 quality since [many users report issues with embeds breaking with H.265](https://github.com/okdargy/fxTikTok/issues/14), but support enabling H.265. To enable high quality H.265 playback, add `?hq=true` or use `hq.tnktok.com`: -| Before | After | +| Before | After | | :--------------------: | :------------------: | | **www**.t**i**ktok.com | **hq**.t**n**ktok.com | +### Combining Modes + +You can combine different modes by using specific hostnames or URL query parameters. For example, if you want to enable H.265 and also see the caption, you can use `hq.a.tnktok.com` or add `?hq=true&addDesc=true` to the URL. + +> You cannot use Direct Mode and Caption Mode simultaneously since they contradict themselves. + ### Why use tnktok.com? We check all the boxes for being one of the best TikTok embedding services with many features that others don't have. Here's a table comparing our service, tnktok.com, with the other TikTok embedding services as well as TikTok's default embeds. diff --git a/src/index.ts b/src/index.ts index e083e04..80fd397 100644 --- a/src/index.ts +++ b/src/index.ts @@ -99,17 +99,26 @@ async function handleVideo(c: any): Promise { const extensions = ['mp4', 'png', 'jpg', 'jpeg', 'webp', 'webm'] if ( - url.hostname.includes('d.tnktok.com') || + url.hostname.includes('d.') || c.req.query('isDirect') === 'true' || extensions.some((suffix) => c.req.path.endsWith(suffix)) ) { if (videoInfo.video.duration > 0) { - return new Response('', { - status: 302, - headers: { - Location: 'https://fxtiktok-rewrite.dargy.workers.dev/generate/video/' + videoInfo.id - } - }) + if ((hq || 'false').toLowerCase() == 'true' || url.hostname.includes('hq.')) { + return new Response('', { + status: 302, + headers: { + Location: 'https://fxtiktok-rewrite.dargy.workers.dev/generate/video/' + videoInfo.id + '?hq=true' + } + }) + } else { + return new Response('', { + status: 302, + headers: { + Location: 'https://fxtiktok-rewrite.dargy.workers.dev/generate/video/' + videoInfo.id + } + }) + } } else { return new Response('', { status: 302, @@ -126,8 +135,8 @@ async function handleVideo(c: any): Promise { const responseContent = await VideoResponse( videoInfo, - (addDesc || 'false').toLowerCase() == 'true' || url.hostname.includes('a.tnktok.com'), - (url.hostname.includes('hq.tnktok.com') || (hq || 'false').toLowerCase() == 'true') + (addDesc || 'false').toLowerCase() == 'true' || url.hostname.includes('a.'), + (hq || 'false').toLowerCase() == 'true' || url.hostname.includes('hq.') ) return returnHTMLResponse(responseContent) } diff --git a/src/services/tiktok.ts b/src/services/tiktok.ts index bc57904..c5d6f2f 100644 --- a/src/services/tiktok.ts +++ b/src/services/tiktok.ts @@ -15,7 +15,8 @@ export async function scrapeVideoData(awemeId: string, author?: string): Promise method: 'GET', headers: { Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0', + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36', Cookie: cookie.getCookiesAsString() }, cf: { diff --git a/src/templates/index.ts b/src/templates/index.ts index ac4e2c8..edde8ec 100644 --- a/src/templates/index.ts +++ b/src/templates/index.ts @@ -2,4 +2,4 @@ export * from './pages/VideoResponse' export * from './pages/Error' export * from './pages/LiveResponse' export * from './pages/WarningResponse' -export * from './pages/Message' \ No newline at end of file +export * from './pages/Message' diff --git a/src/util/responseHelper.ts b/src/util/responseHelper.ts index f01f2d3..5e67b4d 100644 --- a/src/util/responseHelper.ts +++ b/src/util/responseHelper.ts @@ -1,13 +1,9 @@ -export const returnHTMLResponse = ( - content: string, - status?: number, - noCache?: boolean, -): Response => { +export const returnHTMLResponse = (content: string, status?: number, noCache?: boolean): Response => { return new Response(content, { status: status || 200, headers: { - "Content-Type": "text/html; charset=utf-8", - "Cache-Control": noCache ? "no-store" : "public, max-age=3600", - }, - }); -}; \ No newline at end of file + 'Content-Type': 'text/html; charset=utf-8', + 'Cache-Control': noCache ? 'no-store' : 'public, max-age=3600' + } + }) +}