tiktokautouploader 2.7__tar.gz → 2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,13 +25,15 @@ This document provides detailed information about the parameters and usage of th
25
25
  - An array of hashtag strings (e.g., `['#example', '#fun']`) to be added to the video description.
26
26
 
27
27
  - **`sound_name`** (str, optional, default: None)
28
- - The name of the TikTok sound that you want to use for the video. This sound will be applied during the upload. Defaults to None
28
+ - The name of the TikTok sound that you want to use for the video. This sound will be applied during the upload.
29
+ - NOTE: please be specific with sound name (include sound creator name also if possible)
29
30
 
30
31
  - **`sound_aud_vol`** (str, optional, default: `'mix'`)
31
32
  - Determines the volume mix between the TikTok sound and the original video audio. Accepts one of the following options:
32
33
  - `'mix'`: The TikTok sound and original audio will have a 50/50 split.
33
34
  - `'background'`: The original audio will be louder, and the TikTok sound will be faintly heard in the background.
34
35
  - `'main'`: The TikTok sound will be louder, and the original audio will be faintly heard in the background.
36
+ - Defaults to `'mix'` if invalid option chosen
35
37
 
36
38
  - **`schedule`** (str, optional, default: None)
37
39
  - The time you want the video to be uploaded. The format should be `HH:MM`, and the minute (`MM`) must be a multiple of 5. The scheduled time must be at least 15 minutes later than the current local time (unless scheduling for a different day). The time should be in your local time zone.
@@ -50,10 +52,6 @@ This document provides detailed information about the parameters and usage of th
50
52
  - **`suppressprint`** (bool, optional, default: `True`)
51
53
  - Suppresses print messages that indicate the progress of the video upload. It is recommended to set this to `False` when first running the code to see progress and ensure everything works correctly.
52
54
 
53
- ### 📝 IMPORTANT Notes
54
- - **`suppressprint`** (bool, optional, default: `False`)
55
- - When `True`, uppresses print messages that indicate the progress of the video upload. It is recommended to set this to `False` when first running the code to see progress and ensure everything works correctly.
56
-
57
55
 
58
56
  ### 🛠️ Initialization Info
59
57
 
@@ -63,17 +61,14 @@ This document provides detailed information about the parameters and usage of th
63
61
 
64
62
  - Javascript dependencies will be automatically downloaded, once downloaded it will not attempt to download it again unless the files get deleted.
65
63
 
66
- - Runtime might be a 20-30 seconds longer than usual, this is due to libraries being built and runtime should return to normal after first run
64
+ - Runtime might be a 20-30 seconds longer than usual, this is due to libraries being built. Runtime should return to normal after first run
67
65
 
68
66
 
69
67
  ### 📝 Important Notes
70
68
 
71
- - **TikTok Account Recommendations**:
72
- - It is recommended to have a TikTok account with at least a few weeks of cookies built up for the best results.
73
- - Your TikTok account MUST have the ability to save drafts; otherwise, the code will not work correctly. If your account does not have the ability to save drafts, you will be prompted with a warning message during execution
74
69
  - **VERY IMPORTANT: TikTok Account Recommendations**:
75
70
  - It is recommended to have a TikTok account with at least a few weeks of history built up for the best results.
76
- - Your TikTok account MUST have the ability to save drafts; otherwise, the code may not work correctly.
71
+ - If you want to upload your video with TikTok sounds, your TikTok account MUST have the ability to save drafts; otherwise, you can just upload/schedule the video with copyright checks and trending hashtags
77
72
 
78
73
  - **Scheduling Limitations**:
79
74
  - The function allows scheduling up to 10 days in advance.
@@ -83,20 +78,20 @@ This document provides detailed information about the parameters and usage of th
83
78
 
84
79
  - **Captcha solver currently works perfectly for Captcha's of type:**
85
80
  <p align="center">
86
- <img src="READMEimage/CaptchaImage1.jpg" alt="" width="200"/>
81
+ <img src="READMEimage/Captcha1.gif" alt="" width="200"/>
87
82
  </p>
88
83
 
89
84
  <p align="center">
90
- <img src="READMEimage/CaptchaImage2.jpg" alt="" width="200"/>
85
+ <img src="READMEimage/Captcha2.gif" alt="" width="200"/>
91
86
  </p>
92
87
 
93
88
  ## 🕰️ Runtime:
94
- **Total runtime depends on how long TikTok takes to upload your video to their servers, usually it should take anywhere between 1-5 minutes, however, here are approximations on how much runtime is added by each parameter**
89
+ **Total runtime depends on how long TikTok takes to upload your video to their servers, however, here are approximations on how much runtime is added by each parameter**
95
90
 
96
- - **Captcha's:** 3 - 5 secs
97
- - **Adding Sound:** 3 - 4 secs
91
+ - **Captcha's:** 3 - 5 secs (in RARE cases, it can take 10-15 seconds longer)
92
+ - **Adding Sound:** 5 - 10 secs
98
93
  - **Scheduling:** 1 - 3 secs
99
- - **Copyright Check:** 4 - 7 secs (In rare cases it can be longer due to large file size)
94
+ - **Copyright Check:** 2 - 7 secs
100
95
 
101
96
  - **NOTE:** When running for the FIRST TIME ONLY, it may take an extra 20 - 30 seconds at the beginning for the code to start running as libraries are being built
102
97
 
@@ -121,10 +116,4 @@ upload_tiktok(
121
116
  )
122
117
  ```
123
118
 
124
- For more details, please feel free to contact me at haziqmk123@gmail.com or on LinkedIn (on my github profile)
125
-
126
- ### Key Sections:
127
-
128
- - **Parameter Explanations**: Provides detailed descriptions of each parameter, including the valid options and their effects.
129
- - **Other Notes**: Highlights recommendations and limitations related to TikTok accounts and scheduling.
130
- - **Example Usage**: Demonstrates a practical example of how to use the function.
119
+ For more details or if errors persist, please feel free to contact me at haziqmk123@gmail.com or on LinkedIn (on my github profile)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: tiktokautouploader
3
- Version: 2.7
3
+ Version: 2.8
4
4
  Summary: Upload or schedule videos to TikTok with TikTok sounds and hashtags that work.
5
5
  Project-URL: Homepage, https://github.com/haziq-exe/TikTokAutoUploader
6
6
  Author-email: HAZIQ KHALID <haziqmk123@gmail.com>
@@ -3,7 +3,7 @@
3
3
  </div>
4
4
 
5
5
 
6
- ### AUTOMATE TIKTOK UPLOADS. USE TRENDING SOUNDS 🔊, AUTOSOLVES CAPTCHAS 🧠, ADD WORKING HASHTAGS 💯, SCHEDULE UPLOADS 🗓️ AND MORE 🎁
6
+ ### AUTOMATE TIKTOK UPLOADS 🤖. USE TRENDING SOUNDS 🔊, ADD WORKING HASHTAGS 💯, SCHEDULE UPLOADS 🗓️, AUTOSOLVES CAPTCHAS 🧠, AND MORE 🎁
7
7
 
8
8
  [![PyPI version](https://img.shields.io/pypi/v/tiktokautouploader.svg)](https://pypi.org/project/tiktokautouploader/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
9
 
@@ -31,21 +31,22 @@ pip install tiktokautouploader
31
31
 
32
32
  ---
33
33
 
34
-
35
34
  ## ⚙️ Pre-requisites
36
35
 
37
36
  1. **Node.js:** You must have Node.js installed on your system, as some parts of this package rely on JavaScript code. If you don't have Node.js installed, you can download it from [nodejs.org](https://nodejs.org/).
38
37
 
39
- - **Note:** The necessary JavaScript dependencies (`playwright`,`playwright-extra`, `puppeteer-extra-plugin-stealth`) will be automatically installed the first time you run the function, so you don't need to install them manually. Make sure that `npm` (Node.js package manager) is available in your system's PATH.
38
+ - **Note:** The necessary JavaScript dependencies (`playwright`,`playwright-extra`, `puppeteer-extra-plugin-stealth`) will be AUTOMATICALLY installed the first time you run the function, so you don't need to install them manually. Make sure that `npm` (Node.js package manager) is available in your system's PATH.
39
+
40
40
 
41
- 2. **Browser Binaries:** You'll need to install the necessary browser binaries for `playwright`.
41
+ 2. **Browser Binaries:** If you don't have them already, you'll need to install the chromium browser binary for `playwright`.
42
42
 
43
43
  To do so, just run the following command AFTER installing the package:
44
44
 
45
45
  ```bash
46
- playwright install
46
+ python -m playwright install chromium
47
47
  ```
48
48
 
49
+
49
50
  ## 📝 Quick-Start
50
51
 
51
52
  Here's how to upload a video to TikTok with hashtags using `tiktokautouploader`:
@@ -68,7 +69,7 @@ upload_tiktok(video=video_path, description=description, hashtags=hashtags)
68
69
  ### Upload with TikTok Sound
69
70
 
70
71
  ```python
71
- upload_tiktok(video=video_path, description=description, sound_name='trending_sound')
72
+ upload_tiktok(video=video_path, description=description, sound_name='trending_sound', sound_aud_vol='main')
72
73
  ```
73
74
 
74
75
  PLEASE READ DOCUMENTATION FOR MORE INFO.
@@ -101,8 +102,6 @@ This library requires the following dependencies:
101
102
  - `playwright`
102
103
  - `requests`
103
104
  - `Pillow`
104
- - `transformers`
105
- - `torch`
106
105
  - `scikit-learn`
107
106
  - `inference`
108
107
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tiktokautouploader"
7
- version = "2.7"
7
+ version = "2.8"
8
8
  description = "Upload or schedule videos to TikTok with TikTok sounds and hashtags that work."
9
9
  long-description = "file: README.md"
10
10
  long-description-content-type = "text/markdown"
@@ -36,7 +36,7 @@ tags = ["wheel"]
36
36
 
37
37
  [tool.hatch.metadata]
38
38
  name = "tiktokautouploader"
39
- version = "2.7"
39
+ version = "2.8"
40
40
  description = "Upload or schedule videos to TikTok with TikTok sounds and hashtags that work."
41
41
  long_description = "file: README.md"
42
42
  long_description_content_type = "text/markdown"
@@ -1,18 +1,16 @@
1
1
  const { chromium } = require('playwright-extra')
2
2
 
3
- // Load the stealth plugin and use defaults (all tricks to hide playwright usage)
4
- // Note: playwright-extra is compatible with most puppeteer-extra plugins
3
+
5
4
  const stealth = require('puppeteer-extra-plugin-stealth')()
6
5
 
7
- // Add the plugin to playwright (any number of plugins can be added)
8
6
  chromium.use(stealth)
9
7
 
10
- // Define a delay function
11
- function delay(time) {
8
+
9
+ function sleep(time) {
12
10
  return new Promise(resolve => setTimeout(resolve, time));
13
11
  }
14
12
 
15
- // Define a function to check for redirects
13
+
16
14
  async function checkForRedirect(page) {
17
15
  const currentUrl = page.url();
18
16
  const pattern = /^https:\/\/www\.tiktok\.com\/foryou/;
@@ -25,19 +23,18 @@ async function checkForRedirect(page) {
25
23
  const page = await browser.newPage();
26
24
  await page.goto('https://www.tiktok.com/login');
27
25
 
28
- // Loop until redirect is detected
29
26
  while (!redirected) {
30
27
  redirected = await checkForRedirect(page);
31
28
  if (!redirected) {
32
- await delay(1000);
29
+ await sleep(1000);
33
30
  }
34
31
  }
35
32
 
36
- delay(2000)
33
+ sleep(2000)
37
34
  const cookies = await page.context().cookies();
38
35
  const fs = require('fs');
39
36
  fs.writeFileSync('TK_cookies.json', JSON.stringify(cookies, null, 2));
40
37
 
41
- // Close the browser
38
+
42
39
  await browser.close();
43
40
  })();
@@ -11,8 +11,6 @@ import os
11
11
  import warnings
12
12
  warnings.filterwarnings("ignore")
13
13
 
14
- def no_draft_warning():
15
- print("SAVE AS DRAFT BUTTON NOT FOUND; CODE WILL CONTINUE RUNNING BUT VIDEO IS UNLIKELY TO UPLOAD; BEING ABLE TO SAVE AS DRAFT IS ESSENTIAL TO BEING ABLE TO EDIT VIDEOS AND POST, PLEASE BUILD UP ENOUGH ACCOUNT HISTORY TO BE ABLE TO SAVE DRAFTS ")
16
14
 
17
15
  def login_warning():
18
16
  print("NO COOKIES FILE FOUND, PLEASE LOG-IN WHEN PROMPTED")
@@ -24,7 +22,6 @@ def save_cookies(cookies):
24
22
  def run_javascript():
25
23
  js_file_path = pkg_resources.resource_filename(__name__, 'Js_assets/login.js')
26
24
  result = subprocess.run(['node', js_file_path], capture_output=True, text=True)
27
- return result.stdout, result.stderr
28
25
 
29
26
  def install_js_dependencies():
30
27
  js_dir = pkg_resources.resource_filename(__name__, 'Js_assets')
@@ -34,7 +31,6 @@ def install_js_dependencies():
34
31
  print("JavaScript dependencies not found. Installing...")
35
32
  subprocess.run(['npm', 'install', 'playwright', 'playwright-extra', 'puppeteer-extra-plugin-stealth', '--silent'], cwd=js_dir, check=True)
36
33
  else:
37
- print("found dependencies")
38
34
  time.sleep(0.1)
39
35
 
40
36
 
@@ -197,7 +193,6 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
197
193
  video (str) -> path to video to upload
198
194
  description (str) -> description for video
199
195
  hashtags (str)(array) -> hashtags for video
200
- cookies_path (str) -> path to tik tok cookies .json file
201
196
  sound_name (str) -> name of tik tok sound to use for video
202
197
  sound_aud_vol (str) -> volume of tik tok sound, 'main', 'mix' or 'background', check documentation for more info -> https://github.com/haziq-exe/TikTokAutoUploader
203
198
  schedule (str) -> format HH:MM, your local time to upload video
@@ -224,11 +219,14 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
224
219
 
225
220
 
226
221
  with sync_playwright() as p:
227
- browser = p.chromium.launch(headless=True)
222
+
223
+ browser = p.firefox.launch(headless=True)
224
+
228
225
  context = browser.new_context()
229
226
  context.add_cookies(cookies)
230
227
  page = context.new_page()
231
228
  url = 'https://www.tiktok.com/tiktokstudio/upload?from=upload&lang=en'
229
+ url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
232
230
 
233
231
  while retries < 2:
234
232
  try:
@@ -245,6 +243,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
245
243
  captcha = False
246
244
  while detected == False:
247
245
  if page.locator('.upload-text-container').is_visible():
246
+ print("Showed up")
248
247
  detected = True
249
248
  else:
250
249
  if page.locator('div.VerifyBar___StyledDiv-sc-12zaxoy-0.hRJhHT').is_visible():
@@ -254,7 +253,6 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
254
253
  time.sleep(0.1)
255
254
 
256
255
  if captcha == True:
257
- print("CAPTCHA FOUND")
258
256
  image = get_image_src(page)
259
257
  if image:
260
258
  if suppressprint == False:
@@ -291,7 +289,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
291
289
  if attempts > 5:
292
290
  sys.exit("FAILED TO SOLVE CAPTCHA")
293
291
  try:
294
- page.wait_for_selector('.upload-text-container', timeout=10000)
292
+ page.wait_for_selector('.upload-text-container', timeout=5000)
295
293
  os.remove('captcha_image.jpg')
296
294
  if suppressprint == False:
297
295
  print("Captcha Solved")
@@ -308,7 +306,6 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
308
306
  while objectclick == 'N.A':
309
307
  page.click('span.secsdk_captcha_refresh--text')
310
308
  page.wait_for_selector('div.VerifyBar___StyledDiv-sc-12zaxoy-0.hRJhHT')
311
- time.sleep(2)
312
309
  question = page.locator('div.VerifyBar___StyledDiv-sc-12zaxoy-0.hRJhHT').text_content()
313
310
  objectclick = understood_Qs(question)
314
311
  image = get_image_src(page)
@@ -336,7 +333,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
336
333
  if attempts > 5:
337
334
  sys.exit("FAILED TO SOLVE CAPTCHA")
338
335
  try:
339
- page.wait_for_selector('.upload-text-container', timeout=10000)
336
+ page.wait_for_selector('.upload-text-container', timeout=5000)
340
337
  solved = True
341
338
  os.remove('captcha_image.jpg')
342
339
  if suppressprint == False:
@@ -344,13 +341,11 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
344
341
  except:
345
342
  continue
346
343
 
347
-
348
344
 
349
345
  try:
350
346
  page.set_input_files('input[type="file"][accept="video/*"]', f'{video}')
351
347
  except:
352
348
  sys.exit("ERROR: FAILED TO INPUT FILE. Possible Issues: Wifi too slow, file directory wrong, or check documentation to see if captcha is solvable")
353
-
354
349
  page.wait_for_selector('div[data-contents="true"]')
355
350
  page.click('div[data-contents="true"]')
356
351
  if suppressprint == False:
@@ -400,75 +395,10 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
400
395
  except:
401
396
  sys.exit("ERROR: TIK TOK TOOK TOO LONG TO UPLOAD YOUR FILE (>20min). Try again, if issue persists then try a lower file size or different wifi connection")
402
397
 
403
- time.sleep(0.5)
398
+ time.sleep(0.2)
404
399
  if suppressprint == False:
405
400
  print("Tik tok done loading file onto servers")
406
- try:
407
- page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
408
- page.wait_for_selector("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
409
- page.click("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
410
- page.wait_for_selector('div[data-contents="true"]')
411
- page.wait_for_function("document.querySelector('.info-progress-num').textContent.trim() === '100%'", timeout=3000000)
412
- time.sleep(0.5)
413
- except:
414
- no_draft_warning()
415
-
416
- if sound_name != None:
417
- page.click("div.TUXButton-label:has-text('Edit video')")
418
- page.wait_for_selector("input.search-bar-input")
419
- page.fill(f"input.search-bar-input", f"{sound_name}")
420
- time.sleep(0.5)
421
- page.click("div.TUXButton-label:has-text('Search')")
422
- try:
423
- page.wait_for_selector('div.music-card-container')
424
- page.click("div.music-card-container")
425
- page.wait_for_selector("div.TUXButton-label:has-text('Use')")
426
- page.click("div.TUXButton-label:has-text('Use')")
427
- except:
428
- sys.exit("ERROR: SOUND NOT FOUND, VIDEO SAVED AS DRAFT")
429
- try:
430
- page.wait_for_selector('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
431
- page.click('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
432
- time.sleep(0.5)
433
- sliders = page.locator("input.scaleInput")
434
-
435
- if sound_aud_vol == 'background':
436
- slider1 = sliders.nth(0)
437
- bounding_box1 = slider1.bounding_box()
438
- if bounding_box1:
439
- x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.95)
440
- y1 = bounding_box1["y"] + bounding_box1["height"] / 2
441
- page.mouse.click(x1, y1)
442
-
443
- slider2 = sliders.nth(1)
444
- bounding_box2 = slider2.bounding_box()
445
- if bounding_box2:
446
- x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.097)
447
- y2 = bounding_box2["y"] + bounding_box2["height"] / 2
448
- page.mouse.click(x2, y2)
449
-
450
- if sound_aud_vol == 'main':
451
- slider1 = sliders.nth(0)
452
- bounding_box1 = slider1.bounding_box()
453
- if bounding_box1:
454
- x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.097)
455
- y1 = bounding_box1["y"] + bounding_box1["height"] / 2
456
- page.mouse.click(x1, y1)
457
- slider2 = sliders.nth(1)
458
- bounding_box2 = slider2.bounding_box()
459
- if bounding_box2:
460
- x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.95)
461
- y2 = bounding_box2["y"] + bounding_box2["height"] / 2
462
- page.mouse.click(x2, y2)
463
- except:
464
- sys.exit("ERROR ADJUSTING SOUND VOLUME, VIDEO SAVED AS DRAFT")
465
-
466
- page.wait_for_selector("div.TUXButton-label:has-text('Save edit')")
467
- page.click("div.TUXButton-label:has-text('Save edit')")
468
- if suppressprint == False:
469
- print("Added sound")
470
-
471
- page.wait_for_selector('div[data-contents="true"]')
401
+
472
402
  if schedule != None:
473
403
  try:
474
404
  hour = schedule[0:2]
@@ -480,25 +410,25 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
480
410
  sys.exit("SCHEDULE TIME ERROR: PLEASE MAKE SURE YOUR SCHEDULE TIME IS A STRING THAT FOLLOWS THE 24H FORMAT 'HH:MM', VIDEO SAVED AS DRAFT")
481
411
 
482
412
  page.locator('div.TUXRadioStandalone.TUXRadioStandalone--medium').nth(1).click()
483
- time.sleep(0.5)
413
+ time.sleep(0.2)
484
414
  if day != None:
485
415
  page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(1).click()
486
- time.sleep(0.5)
416
+ time.sleep(0.2)
487
417
  try:
488
418
  page.locator(f'span.day.valid:has-text("{day}")').click()
489
419
  except:
490
420
  sys.exit("SCHEDULE DAY ERROR: ERROR WITH SCHEDULED DAY, read documentation for more information on format of day")
491
421
  try:
422
+ time.sleep(1)
492
423
  page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(0).click()
493
- time.sleep(0.5)
494
- page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).scroll_into_view_if_needed()
495
- page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).click()
496
- time.sleep(0.5)
497
- page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(0).click()
498
- time.sleep(0.5)
424
+ time.sleep(0.2)
499
425
  page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').nth(0).scroll_into_view_if_needed()
500
- time.sleep(0.5)
426
+ time.sleep(0.2)
501
427
  page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').nth(0).click()
428
+ time.sleep(0.2)
429
+ page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).scroll_into_view_if_needed()
430
+ page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).click()
431
+ time.sleep(1)
502
432
 
503
433
  if suppressprint == False:
504
434
  print("Done scheduling video")
@@ -506,28 +436,29 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
506
436
  except:
507
437
  sys.exit("SCHEDULING ERROR: VIDEO SAVED AS DRAFT")
508
438
 
439
+ if (schedule == None) and (day != None):
440
+ sys.exit("ERROR: CANT SCHEDULE FOR ANOTHER DAY USING 'day' WITHOUT ALSO INCLUDING TIME OF UPLOAD WITH 'schedule'; PLEASE ALSO INCLUDE TIME WITH 'schedule' PARAMETER")
509
441
 
510
- if copyrightcheck == True:
511
- page.locator(".TUXSwitch-input").nth(0).click()
512
- while copyrightcheck == True:
513
- time.sleep(0.5)
514
- if page.locator("span", has_text="No issues detected.").is_visible():
515
- if suppressprint == False:
516
- print("Copyright check complete")
517
- break
518
- if page.locator("span", has_text="Copyright issues detected.").is_visible():
519
- sys.exit("COPYRIGHT CHECK FAILED: VIDEO SAVED AS DRAFT, COPYRIGHT AUDIO DETECTED FROM TIKTOK")
520
-
521
442
 
522
- try:
443
+ if(sound_name == None):
444
+ if copyrightcheck == True:
445
+ page.locator(".TUXSwitch-input").nth(0).click()
446
+ while copyrightcheck == True:
447
+ time.sleep(0.2)
448
+ if page.locator("span", has_text="No issues detected.").is_visible():
449
+ if suppressprint == False:
450
+ print("Copyright check complete")
451
+ break
452
+ if page.locator("span", has_text="Copyright issues detected.").is_visible():
453
+ sys.exit("COPYRIGHT CHECK FAILED: COPYRIGHT AUDIO DETECTED FROM TIKTOK")
454
+
523
455
  if schedule == None:
524
456
  page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
525
457
  uploaded = False
526
458
  checks = 0
527
459
  while uploaded == False:
528
460
  if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
529
- print("I see it")
530
- time.sleep(1)
461
+ time.sleep(0.2)
531
462
  break
532
463
  time.sleep(0.2)
533
464
  checks += 1
@@ -541,7 +472,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
541
472
  checks = 0
542
473
  while uploaded == False:
543
474
  if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
544
- time.sleep(1)
475
+ time.sleep(0.2)
545
476
  break
546
477
  time.sleep(0.2)
547
478
  checks += 1
@@ -551,9 +482,148 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
551
482
  break
552
483
  if suppressprint == False:
553
484
  print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
554
- except:
555
- time.sleep(5)
556
- sys.exit("ERROR UPLOADING: VIDEO HAS SAVED AS DRAFT BUT CANT UPLOAD")
557
- time.sleep(1)
485
+
486
+ page.close()
487
+
488
+ else:
489
+ try:
490
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
491
+ except:
492
+ sys.exit("SAVE AS DRAFT BUTTON NOT FOUND; CANNOT ADD SOUND WITHOUT ABILITY TO SAVE DRAFTS")
493
+
494
+ time.sleep(0.5)
495
+ page.close()
496
+
497
+ browser = p.chromium.launch(headless=True)
498
+
499
+ context = browser.new_context()
500
+ context.add_cookies(cookies)
501
+ page = context.new_page()
502
+ url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
503
+
504
+ while retries < 2:
505
+ try:
506
+ page.goto(url2, timeout=30000)
507
+ except:
508
+ retries +=1
509
+ time.sleep(5)
510
+ if retries == 2:
511
+ sys.exit("ERROR: TIK TOK PAGE FAILED TO LOAD, try again.")
512
+ else:
513
+ break
514
+
515
+ try:
516
+ page.wait_for_selector("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
517
+ page.click("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
518
+ page.wait_for_selector('div[data-contents="true"]')
519
+ page.wait_for_function("document.querySelector('.info-progress-num').textContent.trim() === '100%'", timeout=3000000)
520
+ time.sleep(0.2)
521
+ except:
522
+ sys.exit("ERROR ADDING SOUND: Video saved as draft")
523
+
524
+ if sound_name != None:
525
+ page.click("div.TUXButton-label:has-text('Edit video')")
526
+ page.wait_for_selector("input.search-bar-input")
527
+ page.fill(f"input.search-bar-input", f"{sound_name}")
528
+ time.sleep(0.2)
529
+ page.click("div.TUXButton-label:has-text('Search')")
530
+ try:
531
+ page.wait_for_selector('div.music-card-container')
532
+ page.click("div.music-card-container")
533
+ page.wait_for_selector("div.TUXButton-label:has-text('Use')")
534
+ page.click("div.TUXButton-label:has-text('Use')")
535
+ except:
536
+ sys.exit(f"ERROR: SOUND '{sound_name}' NOT FOUND")
537
+ try:
538
+ page.wait_for_selector('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
539
+ page.click('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
540
+ time.sleep(0.5)
541
+ sliders = page.locator("input.scaleInput")
542
+
543
+ if sound_aud_vol == 'background':
544
+ slider1 = sliders.nth(0)
545
+ bounding_box1 = slider1.bounding_box()
546
+ if bounding_box1:
547
+ x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.92)
548
+ y1 = bounding_box1["y"] + bounding_box1["height"] / 2
549
+ page.mouse.click(x1, y1)
550
+
551
+ slider2 = sliders.nth(1)
552
+ bounding_box2 = slider2.bounding_box()
553
+ if bounding_box2:
554
+ x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.097)
555
+ y2 = bounding_box2["y"] + bounding_box2["height"] / 2
556
+ page.mouse.click(x2, y2)
557
+
558
+ if sound_aud_vol == 'main':
559
+ slider1 = sliders.nth(0)
560
+ bounding_box1 = slider1.bounding_box()
561
+ if bounding_box1:
562
+ x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.092)
563
+ y1 = bounding_box1["y"] + bounding_box1["height"] / 2
564
+ page.mouse.click(x1, y1)
565
+ slider2 = sliders.nth(1)
566
+ bounding_box2 = slider2.bounding_box()
567
+ if bounding_box2:
568
+ x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.92)
569
+ y2 = bounding_box2["y"] + bounding_box2["height"] / 2
570
+ page.mouse.click(x2, y2)
571
+ except:
572
+ sys.exit("ERROR ADJUSTING SOUND VOLUME: please try again.")
573
+
574
+ page.wait_for_selector("div.TUXButton-label:has-text('Save edit')")
575
+ page.click("div.TUXButton-label:has-text('Save edit')")
576
+ if suppressprint == False:
577
+ print("Added sound")
578
+
579
+ page.wait_for_selector('div[data-contents="true"]')
580
+
581
+ if copyrightcheck == True:
582
+ page.locator(".TUXSwitch-input").nth(0).click()
583
+ while copyrightcheck == True:
584
+ time.sleep(0.2)
585
+ if page.locator("span", has_text="No issues detected.").is_visible():
586
+ if suppressprint == False:
587
+ print("Copyright check complete")
588
+ break
589
+ if page.locator("span", has_text="Copyright issues detected.").is_visible():
590
+ sys.exit("COPYRIGHT CHECK FAILED: VIDEO SAVED AS DRAFT, COPYRIGHT AUDIO DETECTED FROM TIKTOK")
591
+
592
+
593
+ try:
594
+ if schedule == None:
595
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
596
+ uploaded = False
597
+ checks = 0
598
+ while uploaded == False:
599
+ if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
600
+ time.sleep(0.2)
601
+ break
602
+ time.sleep(0.2)
603
+ checks += 1
604
+ if checks > 100:
605
+ time.sleep(10)
606
+ if checks == 150:
607
+ break
608
+ else:
609
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
610
+ uploaded = False
611
+ checks = 0
612
+ while uploaded == False:
613
+ if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
614
+ time.sleep(0.2)
615
+ break
616
+ time.sleep(0.2)
617
+ checks += 1
618
+ if checks > 100:
619
+ time.sleep(10)
620
+ if checks == 150:
621
+ break
622
+ if suppressprint == False:
623
+ print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
624
+ except:
625
+ time.sleep(5)
626
+ sys.exit("ERROR UPLOADING: VIDEO HAS SAVED AS DRAFT BUT CANT UPLOAD")
627
+ time.sleep(1)
558
628
 
559
- page.close()
629
+ page.close()