Skip to content

Commit

Permalink
Browser extension and views fixes (#19)
Browse files Browse the repository at this point in the history
* Browser extension and bug fixes

- Browser extension: you can now run tiktok-to-ytdlp as a browser extension (#18). Screenshots will be added later in the README, along with its publishing on Mozilla Addons
- Fixed a bug where video views were counted incorrectly

* Quick edit to deploy zip file also on this branch

* Improved README & added GitHub link in extension
  • Loading branch information
dinoosauro authored Jun 25, 2024
1 parent 98172ff commit bcd842c
Show file tree
Hide file tree
Showing 36 changed files with 2,543 additions and 7 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/BrowserExtension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This is a basic workflow to help you get started with Actions

name: Generate browser extension

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4

# Runs a single command using the runners shell
- name: Install dependencies & build extension
run: cd extension && npm i && node build.js
- name: Move files
run: cd extension && mv output.zip extension.zip
- name: Get last commit SHA
run: echo "SHORT_COMMIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Create Release
run: gh release create ${{ env.SHORT_COMMIT_SHA }} -t ${{ env.SHORT_COMMIT_SHA }} -n "Note that this release is automatically generated. No testing has been done." --generate-notes "extension/extension.zip"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
input.js
TempLinks
node_modules
extension/output
extension/output.zip
.noupload
node
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ etc. from TikTok, and creates a script to download them with yt-dlp

## Instructions

### From the extension

Download the extension by following the instructions you can find in
[the extension README](./extension/README.md). Then, change the conversion
options (if you want to), and click on the button to start the conversion. The
extesion will take care of everything else.

### From the console

Open the TikTok webpage of the user/sound/etc. you want all the videos
downloaded. Press Ctrl (or Cmd if you are on a Mac) + Shift + I to open the
Developer Tools. Go into the Console tab on the top (if you don't see it, click
Expand All @@ -14,6 +23,8 @@ file. If you prefer a minified version, you can find that
[here](https://raw.githubusercontent.com/Dinoosauro/tiktok-to-ytdlp/main/script.min.js).
Press enter.

### Next steps

The webpage will automatically scroll until no other items are found. Then, a
file called "TikTokLinks.txt" will be downloaded. You now can download the
videos with yt-dlp. An example script is:
Expand Down
70 changes: 70 additions & 0 deletions extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Browser extension

Hello there! Here you can find the source code of the tiktok-to-ytdlp extension.
By installing it, you can use this script from a graphical UI, without needing
to paste anything in the console.

This makes also possible using tiktok-to-ytdlp on mobile browsers, especially on
Firefox for Android. If you're on iOS, look for an extension similar to
TamperMonkey for Safari.

## Installation guide

While you can build the extension yourself, I recommend you to download the
built zip file
[from GitHub Releases](https://github.com/Dinoosauro/tiktok-to-ytdlp/releases/latest).
If you still want to build it, look at the instructions below.

### Chromium

If you still have a Chromium-based browser

1. ~~Switch to Firefox~~ Unzip the extension file
2. Go to the `chrome://extensions` page, and enable the `Developer mode` slider
3. Click on `Load unpacked extension`, and then choose the folder where you've
unzipped the file.
4. You can now use tiktok-to-ytdlp. You should find it in the extension tray (or
on the dropdown menu that appears after clicking the extension icon)

### Firefox

Note: In the future, I might release this on Mozilla Addons. For now, follow
these steps for sideloading it:

1. Go to `about:debugging#/runtime/this-firefox`
2. Click on `Load Temporary Add-on`
3. Choose the .zip file
4. The extension is installed!

## Building guide

You'll need a recent version of Node.js for building it. First, clone **the
entire repository**. Open it in the terminal, and go to the `extension`
directory (`cd extension`). Now install the dependencies for the build script
(`npm i`), and finally run the script (`node build.js`).

You'll find two new things:

- A folder, `output`, with everything needed by the extension
- A zip file, `output.zip`, that you can use for sideloading it on Firefox.

## The UI

At the top, you can switch between three sections, so that you can edit all the
settings of tiktok-to-ytdlp.

![The main UI](./readme_images/MainUI.jpg)

Then, at the bottom, you can start the conversion.

![The scroll UI, with the button to start the operation visible](./readme_images/ScrollUI.jpg)

While the script fetches the videos, you can also obtain a partial .txt file of
the link obtained up to that time.

![The UI while the conversion is being done](./readme_images/ConvertingUI.jpg)

## Issues

If you have any issues with the building process, or in general with the
extension or the script, feel free to open an issue here on GitHub.
14 changes: 14 additions & 0 deletions extension/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const fs = require("fs");
const zip = require("jszip");
(fs.existsSync("output")) && fs.rmSync("output", { recursive: true });
fs.mkdirSync("output");
require("child_process").execSync("cd code/vite && npm i && npx vite build --base=ui");
require("fs-extra").moveSync(`./code/vite/dist`, `./output/ui`);
fs.mkdirSync("output/icons");
for (let item of ["manifest.json", "icons/16.png", "icons/48.png", "icons/128.png"]) fs.copyFileSync(`./code/${item}`, `./output/${item}`);
let firstScript = fs.readFileSync(`../script.js`, "utf-8");
firstScript = firstScript.substring(0, firstScript.indexOf("nodeElaborateCustomArgs();"));
fs.writeFileSync(`./output/extensionHandler.js`, `${firstScript}${fs.readFileSync("./code/extensionHandler.js", "utf-8")}`);
const zipFile = new zip();
for (let file of fs.readdirSync("./output", { recursive: true })) if (fs.statSync(`./output/${file}`).isFile()) zipFile.file(file, fs.readFileSync(`./output/${file}`), { createFolders: true });
zipFile.generateAsync({ type: "nodebuffer" }).then((buffer) => fs.writeFileSync("output.zip", buffer));
3 changes: 3 additions & 0 deletions extension/code/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["svelte.svelte-vscode"]
}
35 changes: 35 additions & 0 deletions extension/code/extensionHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Send to the UI the current "conversion" status
*/
function updateClient() {
(chrome ?? browser).runtime.sendMessage((chrome ?? browser).runtime.id, { operation: scriptOptions.node.resolve && !scriptOptions.node.isResolveTime });
}
(chrome ?? browser).runtime.onMessage.addListener((message) => {
switch (message.action) {
case "start": { // Start running the script
scriptOptions = { ...scriptOptions, ...message.content }; // Add the values from the object provided
const avoidNullishValues = new Map([ // If those values are null (Svelte might save them as null if nothing is provided), sign them as default
["scrolling_min_time", 1300],
["scrolling_max_time", 2100],
["min_views", -1]
]);
for (let [key, value] of avoidNullishValues) if (scriptOptions[key] === null) scriptOptions[key] = value;
if (scriptOptions.advanced.maximum_downloads === null) scriptOptions.advanced.maximum_downloads = Infinity;
scriptOptions.node.isNode = true; // Mark this script as it is being used in Node via Puppeteer, so that a Promise will be made, resolved when it's time to download everything. While the download would start in any case, in this way we can also notify the extension UI that the conversion has ended.
startDownload().then((arr) => {
downloadScript(arr.join("\n"), true);
updateClient();
});
updateClient();
break;
}
case "partial": { // Download a part of the script
downloadScript(requestTxtNow().join("\n"), true);
break;
}
case "requestOperation": { // Ask if a conversion is being done or not.
updateClient();
break;
}
}
});
Binary file added extension/code/icons/128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added extension/code/icons/16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added extension/code/icons/48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions extension/code/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"manifest_version": 3,
"name": "tiktok-to-ytdlp",
"description": "Get a .txt file of all the TikTok videos from an user/audio/hashtag/liked videos/saved videos etc, so that they can be downloaded with yt-dlp.",
"version": "1.0",
"permissions": ["storage"],
"action": {
"default_popup": "./ui/index.html"
},
"content_scripts": [
{
"js": [
"extensionHandler.js"
],
"matches": [
"*://*.tiktok.com/*"
]
}
],
"icons": {
"16": "./icons/16.png",
"48": "./icons/48.png",
"128": "./icons/128.png"
},
"browser_specific_settings": {
"gecko": {
"id": "{07b46526-6164-427c-a135-542654e1da00}"
}
}
}
24 changes: 24 additions & 0 deletions extension/code/vite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
15 changes: 15 additions & 0 deletions extension/code/vite/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>tiktok-to-ytdlp</title>
</head>

<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>

</html>
Loading

0 comments on commit bcd842c

Please sign in to comment.