tiktokautouploader 2.95__py2.py3-none-any.whl → 3.2__py2.py3-none-any.whl

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.
@@ -1,8 +1,8 @@
1
1
  from playwright.sync_api import sync_playwright
2
2
  import json
3
3
  import time
4
- import inference
5
4
  import subprocess
5
+ from inference_sdk import InferenceHTTPClient
6
6
  import pkg_resources
7
7
  import requests
8
8
  from PIL import Image
@@ -11,15 +11,26 @@ import os
11
11
  import warnings
12
12
  warnings.simplefilter("ignore")
13
13
 
14
- def login_warning():
15
- print("NO COOKIES FILE FOUND, PLEASE LOG-IN WHEN PROMPTED")
14
+
15
+ def check_for_updates():
16
+ current_version = pkg_resources.get_distribution("tiktokautouploader").version
17
+ response = requests.get("https://pypi.org/pypi/tiktokautouploader/json")
18
+
19
+ if response.status_code == 200:
20
+ latest_version = response.json()["info"]["version"]
21
+ if current_version != latest_version:
22
+ print(f"WARNING: You are using version {current_version} of tiktokautouploader, "
23
+ f"PLEASE UPDATE TO LATEST VERSION {latest_version} FOR BEST EXPERIENCE.")
24
+
25
+ def login_warning(accountname):
26
+ print(f"NO COOKIES FILE FOUND FOR ACCOUNT {accountname}, PLEASE LOG-IN TO {accountname} WHEN PROMPTED")
16
27
 
17
28
  def save_cookies(cookies):
18
29
  with open('TK_cookies.json', 'w') as file:
19
30
  json.dump(cookies, file, indent=4)
20
31
 
21
- def check_expiry():
22
- with open('TK_cookies.json', 'r') as file:
32
+ def check_expiry(accountname):
33
+ with open(f'TK_cookies_{accountname}.json', 'r') as file:
23
34
  cookies = json.load(file)
24
35
 
25
36
  current_time = int(time.time())
@@ -128,21 +139,27 @@ def download_image(image_url):
128
139
  f.write(response.content)
129
140
  return image_path
130
141
 
131
-
132
142
  def run_inference_on_image_tougher(image_path, object):
133
143
 
134
- model = inference.get_model("captcha-2-6ehbe/2")
135
- results = model.infer(image=image_path)
144
+ k = 'n|KIeDZnRZiJ};iVHz;R'
145
+ rk = ''.join(chr((ord(c) - 3) % 256) for c in k)
146
+
147
+ CLIENT = InferenceHTTPClient(
148
+ api_url="https://detect.roboflow.com",
149
+ api_key=f"{rk}"
150
+ )
151
+
152
+ results = CLIENT.infer(image_path, model_id="captcha-2-6ehbe/2")
136
153
 
137
154
  class_names = []
138
155
  bounding_boxes = []
139
- for obj in results[0].predictions:
140
- class_names.append(obj.class_name)
156
+ for obj in results['predictions']:
157
+ class_names.append(obj['class'])
141
158
  bounding_boxes.append({
142
- "x": obj.x,
143
- "y": obj.y,
144
- "width": obj.width,
145
- "height": obj.height
159
+ "x": obj['x'],
160
+ "y": obj['y'],
161
+ "width": obj['width'],
162
+ "height": obj['height']
146
163
  })
147
164
 
148
165
  bounding_box = []
@@ -157,34 +174,40 @@ def run_inference_on_image_tougher(image_path, object):
157
174
 
158
175
  def run_inference_on_image(image_path):
159
176
 
160
- model = inference.get_model("tk-3nwi9/2")
161
- results = model.infer(image=image_path)
177
+ k = 'n|KIeDZnRZiJ};iVHz;R'
178
+ rk = ''.join(chr((ord(c) - 3) % 256) for c in k)
179
+
180
+ CLIENT = InferenceHTTPClient(
181
+ api_url="https://detect.roboflow.com",
182
+ api_key=f"{rk}"
183
+ )
184
+
185
+ results = CLIENT.infer(image_path, model_id="tk-3nwi9/2")
162
186
 
163
187
  class_names = []
164
188
  bounding_boxes = []
165
- for obj in results[0].predictions:
166
- class_names.append(obj.class_name)
189
+ for obj in results['predictions']:
190
+ class_names.append(obj['class'])
167
191
  bounding_boxes.append({
168
- "x": obj.x,
169
- "y": obj.y,
170
- "width": obj.width,
171
- "height": obj.height
192
+ "x": obj['x'],
193
+ "y": obj['y'],
194
+ "width": obj['width'],
195
+ "height": obj['height']
172
196
  })
173
197
 
174
198
  already_written = []
175
199
  bounding_box = []
176
200
  class_to_click = []
177
- for i, classes in enumerate(class_names):
178
- if classes in already_written:
179
- class_to_click.append(classes)
201
+ for i, detected_class in enumerate(class_names):
202
+ if detected_class in already_written:
203
+ class_to_click.append(detected_class)
180
204
  bounding_box.append(bounding_boxes[i])
181
- index = already_written.index(classes)
205
+ index = already_written.index(detected_class)
182
206
  bounding_box.append(bounding_boxes[index])
183
207
 
184
- already_written.append(classes)
208
+ already_written.append(detected_class)
185
209
 
186
210
  found = False
187
-
188
211
  if len(class_to_click) == 1:
189
212
  found = True
190
213
 
@@ -212,13 +235,14 @@ def click_on_objects(page, object_coords):
212
235
 
213
236
 
214
237
 
215
- def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_vol='mix', schedule=None, day=None, copyrightcheck=False, suppressprint=False):
238
+ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=None, sound_aud_vol='mix', schedule=None, day=None, copyrightcheck=False, suppressprint=False, headless=True):
216
239
 
217
240
  """
218
241
  UPLOADS VIDEO TO TIKTOK
219
242
  ------------------------------------------------------------------------------------------------------------------------------------------------c
220
243
  video (str) -> path to video to upload
221
244
  description (str) -> description for video
245
+ accountname (str) -> account to upload on
222
246
  hashtags (str)(array) -> hashtags for video
223
247
  sound_name (str) -> name of tik tok sound to use for video
224
248
  sound_aud_vol (str) -> volume of tik tok sound, 'main', 'mix' or 'background', check documentation for more info -> https://github.com/haziq-exe/TikTokAutoUploader
@@ -226,40 +250,51 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
226
250
  day (int) -> day to schedule video for, check documentation for more info -> https://github.com/haziq-exe/TikTokAutoUploader
227
251
  copyrightcheck (bool) -> include copyright check or not; CODE FAILS IF FAIL COPYRIGHT CHECK
228
252
  suppressprint (bool) -> True means function doesnt print anything to provide updates on progress
253
+ headless (bool) -> run in headless mode or not
229
254
  --------------------------------------------------------------------------------------------------------------------------------------------
230
255
  """
256
+ try:
257
+ check_for_updates()
258
+ except:
259
+ time.sleep(0.1)
231
260
 
232
261
  retries = 0
233
262
  cookie_read = False
234
263
  oldQ = 'N.A'
235
264
 
236
- if os.path.exists('TK_cookies.json'):
237
- cookies, cookie_read = read_cookies(cookies_path='TK_cookies.json')
238
- expired = check_expiry()
265
+ if accountname == None:
266
+ sys.exit("PLEASE ENTER NAME OF ACCOUNT TO POST ON, READ DOCUMENTATION FOR MORE INFO")
267
+
268
+ if os.path.exists(f'TK_cookies_{accountname}.json'):
269
+ cookies, cookie_read = read_cookies(cookies_path=f'TK_cookies_{accountname}.json')
270
+ expired = check_expiry(accountname=accountname)
239
271
  if expired == True:
240
- os.remove('TK_cookies.json')
241
- print("COOKIES EXPIRED, PLEASE LOG-IN AGAIN")
272
+ os.remove(f'TK_cookies_{accountname}.json')
273
+ print(f"COOKIES EXPIRED FOR ACCOUNT {accountname}, PLEASE LOG-IN AGAIN")
242
274
  cookie_read = False
243
275
 
244
276
  if cookie_read == False:
245
277
  install_js_dependencies()
246
- login_warning()
278
+ login_warning(accountname=accountname)
247
279
  result = run_javascript()
280
+ os.rename('TK_cookies.json', f'TK_cookies_{accountname}.json')
248
281
 
249
- cookies, cookie_read = read_cookies("TK_cookies.json")
282
+ cookies, cookie_read = read_cookies(f"TK_cookies_{accountname}.json")
250
283
  if cookie_read == False:
251
284
  sys.exit("ERROR READING COOKIES")
252
285
 
253
-
286
+
254
287
  with sync_playwright() as p:
255
288
 
256
- browser = p.webkit.launch(headless=False)
257
-
289
+ browser = p.firefox.launch(headless=headless)
258
290
  context = browser.new_context()
259
291
  context.add_cookies(cookies)
260
292
  page = context.new_page()
261
293
  url = 'https://www.tiktok.com/tiktokstudio/upload?from=upload&lang=en'
262
294
 
295
+ if suppressprint == False:
296
+ print(f"Uploading to account '{accountname}'")
297
+
263
298
  while retries < 2:
264
299
  try:
265
300
  page.goto(url, timeout=30000)
@@ -298,7 +333,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
298
333
  question = page.locator('div.VerifyBar___StyledDiv-sc-12zaxoy-0.hRJhHT').text_content()
299
334
  if time.time() - start_time > 2:
300
335
  break
301
- if 'Select 2 objects that are the same' in question:
336
+ if 'Select 2 objects that are the same' in question or 'Select two objects that are the same' in question:
302
337
  found = False
303
338
  while found == False:
304
339
  page.click('span.secsdk_captcha_refresh--text')
@@ -319,7 +354,10 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
319
354
  image_width_real, image_height_real = image_size
320
355
 
321
356
  webpage_coords = convert_to_webpage_coordinates(b_box, image_x, image_y, image_height_web, image_width_web, image_height_real, image_width_real)
357
+ if not webpage_coords:
358
+ webpage_coords.append((image_x + 50, image_y + 50))
322
359
  click_on_objects(page, webpage_coords)
360
+ page.click("div.verify-captcha-submit-button")
323
361
  time.sleep(0.5)
324
362
  if attempts > 5:
325
363
  sys.exit("FAILED TO SOLVE CAPTCHA")
@@ -327,6 +365,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
327
365
  if page.locator("div.captcha_verify_message.captcha_verify_message-pass").is_visible():
328
366
  solved = True
329
367
  showedup = True
368
+ os.remove('captcha_image.jpg')
330
369
  if page.locator("div.captcha_verify_message.captcha_verify_message-fail").is_visible():
331
370
  showedup = True
332
371
  oldQ = question
@@ -363,9 +402,11 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
363
402
  image_width_real, image_height_real = image_size
364
403
 
365
404
  webpage_coords = convert_to_webpage_coordinates(b_box, image_x, image_y, image_height_web, image_width_web, image_height_real, image_width_real)
366
-
405
+ if not webpage_coords:
406
+ webpage_coords.append((image_x + 50, image_y + 50))
367
407
  click_on_objects(page, webpage_coords)
368
408
  page.click("div.verify-captcha-submit-button")
409
+ time.sleep(1)
369
410
  if attempts > 20:
370
411
  sys.exit("FAILED TO SOLVE CAPTCHA")
371
412
  showedup = False
@@ -431,13 +472,16 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
431
472
  print("Description and Hashtags added")
432
473
 
433
474
  try:
434
- page.wait_for_function("document.querySelector('.info-progress-num').textContent.trim() === '100%'", timeout=12000000)
475
+ page.wait_for_selector('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")[aria-disabled="false"]', timeout=12000000)
435
476
  except:
436
477
  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")
437
478
 
438
479
  time.sleep(0.2)
439
480
  if suppressprint == False:
440
481
  print("Tik tok done loading file onto servers")
482
+
483
+ if (schedule == None) and (day != None):
484
+ 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")
441
485
 
442
486
  if schedule != None:
443
487
  try:
@@ -449,31 +493,39 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
449
493
  except:
450
494
  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")
451
495
 
452
- page.locator('div.TUXRadioStandalone.TUXRadioStandalone--medium').nth(1).click()
453
- time.sleep(1)
454
- if page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).is_visible():
455
- page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).click()
456
- time.sleep(0.2)
457
- else:
458
- if page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(1).is_visible():
459
- time.sleep(0.2)
496
+ page.locator('div.TUXRadioStandalone.TUXRadioStandalone--medium:has(input[value="schedule"])').click()
497
+ # time.sleep(1)
498
+ visible = False
499
+ while visible == False:
500
+ if page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).is_visible():
501
+ page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).click()
502
+ visible = True
503
+ time.sleep(0.1)
504
+ else:
505
+ if page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(1).is_visible():
506
+ visible = True
507
+ time.sleep(0.1)
460
508
  if day != None:
461
- page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(1).click()
509
+ page.locator('div.TUXTextInputCore-leadingIconWrapper:has(svg > path[d="M15 3a1 1 0 0 0-1 1v3h-1.4c-3.36 0-5.04 0-6.32.65a6 6 0 0 0-2.63 2.63C3 11.56 3 13.24 3 16.6v16.8c0 3.36 0 5.04.65 6.32a6 6 0 0 0 2.63 2.63c1.28.65 2.96.65 6.32.65h22.8c3.36 0 5.04 0 6.32-.65a6 6 0 0 0 2.63-2.63c.65-1.28.65-2.96.65-6.32V16.6c0-3.36 0-5.04-.65-6.32a6 6 0 0 0-2.63-2.63C40.44 7 38.76 7 35.4 7H34V4a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v3H18V4a1 1 0 0 0-1-1h-2Zm-2.4 8H14v3a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-3h12v3a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-3h1.4c1.75 0 2.82 0 3.62.07a5.11 5.11 0 0 1 .86.14h.03a2 2 0 0 1 .88.91 5.11 5.11 0 0 1 .14.86c.07.8.07 1.87.07 3.62v1.9H7v-1.9c0-1.75 0-2.82.07-3.62a5.12 5.12 0 0 1 .14-.86v-.03a2 2 0 0 1 .88-.87l.03-.01a5.11 5.11 0 0 1 .86-.14c.8-.07 1.87-.07 3.62-.07ZM7 22.5h34v10.9c0 1.75 0 2.82-.07 3.62a5.11 5.11 0 0 1-.14.86v.03a2 2 0 0 1-.88.87l-.03.01a5.11 5.11 0 0 1-.86.14c-.8.07-1.87.07-3.62.07H12.6c-1.75 0-2.82 0-3.62-.07a5.11 5.11 0 0 1-.89-.15 2 2 0 0 1-.87-.87l-.01-.03a5.12 5.12 0 0 1-.14-.86C7 36.22 7 35.15 7 33.4V22.5Z"])').click()
462
510
  time.sleep(0.2)
463
511
  try:
464
512
  page.locator(f'span.day.valid:has-text("{day}")').click()
465
513
  except:
466
514
  sys.exit("SCHEDULE DAY ERROR: ERROR WITH SCHEDULED DAY, read documentation for more information on format of day")
467
515
  try:
468
- time.sleep(1)
469
- page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(0).click()
470
516
  time.sleep(0.2)
471
- page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').nth(0).scroll_into_view_if_needed()
517
+ page.locator('div.TUXTextInputCore-leadingIconWrapper:has(svg > path[d="M24 2a22 22 0 1 0 0 44 22 22 0 0 0 0-44ZM6 24a18 18 0 1 1 36 0 18 18 0 0 1-36 0Z"])').click()
518
+ time.sleep(0.2)
519
+ page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').scroll_into_view_if_needed()
472
520
  time.sleep(0.2)
473
- page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').nth(0).click()
521
+ page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').click()
474
522
  time.sleep(0.2)
475
- page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).scroll_into_view_if_needed()
476
- page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).click()
523
+ if page.locator("div.tiktok-timepicker-time-picker-container").is_visible():
524
+ time.sleep(0.1)
525
+ else:
526
+ page.locator('div.TUXTextInputCore-leadingIconWrapper:has(svg > path[d="M24 2a22 22 0 1 0 0 44 22 22 0 0 0 0-44ZM6 24a18 18 0 1 1 36 0 18 18 0 0 1-36 0Z"])').click()
527
+ page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-left:has-text("{hour}")').scroll_into_view_if_needed()
528
+ page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-left:has-text("{hour}")').click()
477
529
  time.sleep(1)
478
530
 
479
531
  if suppressprint == False:
@@ -481,93 +533,14 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
481
533
 
482
534
  except:
483
535
  sys.exit("SCHEDULING ERROR: VIDEO SAVED AS DRAFT")
484
-
485
- if (schedule == None) and (day != None):
486
- 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")
487
-
488
- if(sound_name == None):
489
- if copyrightcheck == True:
490
- page.locator(".TUXSwitch-input").nth(0).click()
491
- while copyrightcheck == True:
492
- time.sleep(0.2)
493
- if page.locator("span", has_text="No issues detected.").is_visible():
494
- if suppressprint == False:
495
- print("Copyright check complete")
496
- break
497
- if page.locator("span", has_text="Copyright issues detected.").is_visible():
498
- sys.exit("COPYRIGHT CHECK FAILED: COPYRIGHT AUDIO DETECTED FROM TIKTOK")
499
-
500
- if schedule == None:
501
- page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
502
- uploaded = False
503
- checks = 0
504
- while uploaded == False:
505
- if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
506
- time.sleep(0.2)
507
- break
508
- time.sleep(0.2)
509
- checks += 1
510
- if checks > 100:
511
- time.sleep(10)
512
- if checks == 150:
513
- break
514
- else:
515
- page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
516
- uploaded = False
517
- checks = 0
518
- while uploaded == False:
519
- if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
520
- time.sleep(0.2)
521
- break
522
- time.sleep(0.2)
523
- checks += 1
524
- if checks > 100:
525
- time.sleep(10)
526
- if checks == 150:
527
- break
528
- if suppressprint == False:
529
- print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
530
-
531
- page.close()
532
536
 
533
- else:
537
+ sound_fail = False
538
+ if sound_name != None:
534
539
  try:
535
- page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
536
- except:
537
- sys.exit("SAVE AS DRAFT BUTTON NOT FOUND; CANNOT ADD SOUND WITHOUT ABILITY TO SAVE DRAFTS")
538
-
539
- time.sleep(0.5)
540
- page.close()
541
-
542
- browser = p.chromium.launch(headless=True)
543
-
544
- context = browser.new_context()
545
- context.add_cookies(cookies)
546
- page = context.new_page()
547
- url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
548
-
549
- while retries < 2:
550
- try:
551
- page.goto(url2, timeout=30000)
552
- except:
553
- retries +=1
554
- time.sleep(5)
555
- if retries == 2:
556
- sys.exit("ERROR: TIK TOK PAGE FAILED TO LOAD, try again.")
557
- else:
558
- break
559
-
560
- try:
561
- 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']")
562
- 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']")
563
- page.wait_for_selector('div[data-contents="true"]')
564
- page.wait_for_function("document.querySelector('.info-progress-num').textContent.trim() === '100%'", timeout=3000000)
565
- time.sleep(0.2)
566
- except:
567
- sys.exit("ERROR ADDING SOUND: Video saved as draft")
568
-
569
- if sound_name != None:
570
540
  page.click("div.TUXButton-label:has-text('Edit video')")
541
+ except:
542
+ sound_fail = True
543
+ if sound_fail == False:
571
544
  page.wait_for_selector("input.search-bar-input")
572
545
  page.fill(f"input.search-bar-input", f"{sound_name}")
573
546
  time.sleep(0.2)
@@ -620,11 +593,12 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
620
593
  page.click("div.TUXButton-label:has-text('Save edit')")
621
594
  if suppressprint == False:
622
595
  print("Added sound")
623
-
596
+
597
+ if sound_fail == False:
624
598
  page.wait_for_selector('div[data-contents="true"]')
625
599
 
626
600
  if copyrightcheck == True:
627
- page.locator(".TUXSwitch-input").nth(0).click()
601
+ page.click('div.TUXSwitch:has(label.TUXSwitch-label:has-text("Run a copyright check")) input.TUXSwitch-input')
628
602
  while copyrightcheck == True:
629
603
  time.sleep(0.2)
630
604
  if page.locator("span", has_text="No issues detected.").is_visible():
@@ -671,4 +645,148 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
671
645
  sys.exit("ERROR UPLOADING: VIDEO HAS SAVED AS DRAFT BUT CANT UPLOAD")
672
646
  time.sleep(1)
673
647
 
674
- page.close()
648
+ page.close()
649
+ else:
650
+ try:
651
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
652
+ except:
653
+ sys.exit("SAVE AS DRAFT BUTTON NOT FOUND; Please try account that has ability to save as draft")
654
+
655
+ time.sleep(0.5)
656
+ page.close()
657
+
658
+ browser = p.chromium.launch(headless=headless)
659
+
660
+ context = browser.new_context()
661
+ context.add_cookies(cookies)
662
+ page = context.new_page()
663
+ url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
664
+
665
+ while retries < 2:
666
+ try:
667
+ page.goto(url2, timeout=30000)
668
+ except:
669
+ retries +=1
670
+ time.sleep(5)
671
+ if retries == 2:
672
+ sys.exit("ERROR: TIK TOK PAGE FAILED TO LOAD, try again.")
673
+ else:
674
+ break
675
+
676
+ try:
677
+ 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']")
678
+ 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']")
679
+ page.wait_for_selector('div[data-contents="true"]')
680
+ time.sleep(0.2)
681
+ except:
682
+ sys.exit("ERROR ADDING SOUND: Video saved as draft")
683
+
684
+ if sound_name != None:
685
+ page.click("div.TUXButton-label:has-text('Edit video')")
686
+ page.wait_for_selector("input.search-bar-input")
687
+ page.fill(f"input.search-bar-input", f"{sound_name}")
688
+ time.sleep(0.2)
689
+ page.click("div.TUXButton-label:has-text('Search')")
690
+ try:
691
+ page.wait_for_selector('div.music-card-container')
692
+ page.click("div.music-card-container")
693
+ page.wait_for_selector("div.TUXButton-label:has-text('Use')")
694
+ page.click("div.TUXButton-label:has-text('Use')")
695
+ except:
696
+ sys.exit(f"ERROR: SOUND '{sound_name}' NOT FOUND")
697
+ try:
698
+ page.wait_for_selector('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
699
+ page.click('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
700
+ time.sleep(0.5)
701
+ sliders = page.locator("input.scaleInput")
702
+
703
+ if sound_aud_vol == 'background':
704
+ slider1 = sliders.nth(0)
705
+ bounding_box1 = slider1.bounding_box()
706
+ if bounding_box1:
707
+ x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.92)
708
+ y1 = bounding_box1["y"] + bounding_box1["height"] / 2
709
+ page.mouse.click(x1, y1)
710
+
711
+ slider2 = sliders.nth(1)
712
+ bounding_box2 = slider2.bounding_box()
713
+ if bounding_box2:
714
+ x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.097)
715
+ y2 = bounding_box2["y"] + bounding_box2["height"] / 2
716
+ page.mouse.click(x2, y2)
717
+
718
+ if sound_aud_vol == 'main':
719
+ slider1 = sliders.nth(0)
720
+ bounding_box1 = slider1.bounding_box()
721
+ if bounding_box1:
722
+ x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.092)
723
+ y1 = bounding_box1["y"] + bounding_box1["height"] / 2
724
+ page.mouse.click(x1, y1)
725
+ slider2 = sliders.nth(1)
726
+ bounding_box2 = slider2.bounding_box()
727
+ if bounding_box2:
728
+ x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.92)
729
+ y2 = bounding_box2["y"] + bounding_box2["height"] / 2
730
+ page.mouse.click(x2, y2)
731
+ except:
732
+ sys.exit("ERROR ADJUSTING SOUND VOLUME: please try again.")
733
+
734
+ page.wait_for_selector("div.TUXButton-label:has-text('Save edit')")
735
+ page.click("div.TUXButton-label:has-text('Save edit')")
736
+ if suppressprint == False:
737
+ print("Added sound")
738
+
739
+
740
+ page.wait_for_selector('div[data-contents="true"]')
741
+
742
+ if copyrightcheck == True:
743
+ page.click('div.TUXSwitch:has(label.TUXSwitch-label:has-text("Run a copyright check")) input.TUXSwitch-input')
744
+ while copyrightcheck == True:
745
+ time.sleep(0.2)
746
+ if page.locator("span", has_text="No issues detected.").is_visible():
747
+ if suppressprint == False:
748
+ print("Copyright check complete")
749
+ break
750
+ if page.locator("span", has_text="Copyright issues detected.").is_visible():
751
+ sys.exit("COPYRIGHT CHECK FAILED: VIDEO SAVED AS DRAFT, COPYRIGHT AUDIO DETECTED FROM TIKTOK")
752
+
753
+
754
+ try:
755
+ if schedule == None:
756
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
757
+ uploaded = False
758
+ checks = 0
759
+ while uploaded == False:
760
+ if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
761
+ time.sleep(0.2)
762
+ break
763
+ time.sleep(0.2)
764
+ checks += 1
765
+ if checks > 100:
766
+ time.sleep(10)
767
+ if checks == 150:
768
+ break
769
+ else:
770
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
771
+ uploaded = False
772
+ checks = 0
773
+ while uploaded == False:
774
+ if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
775
+ time.sleep(0.2)
776
+ break
777
+ time.sleep(0.2)
778
+ checks += 1
779
+ if checks > 100:
780
+ time.sleep(10)
781
+ if checks == 150:
782
+ break
783
+ if suppressprint == False:
784
+ print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
785
+ except:
786
+ time.sleep(5)
787
+ sys.exit("ERROR UPLOADING: VIDEO HAS SAVED AS DRAFT BUT CANT UPLOAD")
788
+ time.sleep(1)
789
+
790
+ page.close()
791
+
792
+ return "Completed"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: tiktokautouploader
3
- Version: 2.95
3
+ Version: 3.2
4
4
  Summary: Upload or schedule videos to TikTok with viral TikTok sounds and hashtags.
5
5
  Project-URL: Homepage, https://github.com/haziq-exe/TikTokAutoUploader
6
6
  Author-email: HAZIQ <haziqmk123@gmail.com>
@@ -29,9 +29,8 @@ Description-Content-Type: text/markdown
29
29
 
30
30
  [![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)
31
31
 
32
-
33
32
  <p align="center">
34
- <img src="READMEimage/READMEimg.png" alt="" width="150"/>
33
+ <img src="READMEimage/READMEGIF.gif" alt="" width="900"/>
35
34
  </p>
36
35
 
37
36
  ## 🚀 Features
@@ -41,7 +40,10 @@ Description-Content-Type: text/markdown
41
40
  - **🗓 Schedule Uploads:** Upload videos at specific times or upto 10 days in advance with our scheduling feature.
42
41
  - **🔍 Copyright Check:** Ensure your video is safe from copyright claims before uploading.
43
42
  - **🏷 Add Working Hashtags:** Increase your reach by adding effective hashtags that actually work.
43
+ - **⏰ Cutdown on upload time:** Upload to TikTok with way less hassle and much more speed using our library.
44
+ - **📝 Upload to different accounts:** Stay organized and on top of multiple different accounts with our multi-account functionality.
44
45
 
46
+ ⭐️ If you like this project please feel free to star it, Thank you.
45
47
 
46
48
  ## 📦 Installation
47
49
 
@@ -51,6 +53,8 @@ Description-Content-Type: text/markdown
51
53
  pip install tiktokautouploader
52
54
  ```
53
55
 
56
+ **NOTE:** IF YOU HAVE INSTALLED BEFORE, PLEASE MAKE SURE YOU UPGRADE TO THE LATEST VERSION.
57
+
54
58
  ---
55
59
 
56
60
  ## ⚙️ Pre-requisites
@@ -60,7 +64,7 @@ pip install tiktokautouploader
60
64
  - **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.
61
65
 
62
66
 
63
- 2. **Browser Binaries:** If you don't have them already, you'll need to install the browser binaries for `playwright`.
67
+ 2. **Browser Binaries:** If you don't have them already, you'll need to install the browser binaries for `playwright`. This library uses chromium and firefox.
64
68
 
65
69
  to do so, just run the following command AFTER installing the package:
66
70
 
@@ -68,11 +72,13 @@ pip install tiktokautouploader
68
72
  python -m playwright install
69
73
  ```
70
74
 
75
+ **NOTE:** If you want to add sounds to your TikTok, you MUST have the ability to save drafts. If you don't want to add sounds then you don't need this feature.
76
+
71
77
 
72
78
  ## 📝 Quick-Start
73
79
 
74
80
  **NOTE:** It is highly recommended you read DOCUMENTATION.md before using the library.
75
- The first time you run the code, you will be prompted to log-in, this will only occur the first time the function is used. Check documentation for more info.
81
+ The first time you run the code for an account, you will be prompted to log-in, this will only occur the first time the function is used for the account. Check documentation for more info.
76
82
 
77
83
  ## Upload with hashtags
78
84
 
@@ -81,16 +87,17 @@ from tiktokautouploader import upload_tiktok
81
87
 
82
88
  video_path = 'path/to/your/video.mp4'
83
89
  description = 'Check out my latest TikTok video!'
90
+ accountname = 'mytiktokaccount'
84
91
  hashtags = ['#fun', '#viral']
85
92
 
86
- upload_tiktok(video=video_path, description=description, hashtags=hashtags)
93
+ upload_tiktok(video=video_path, description=description, accountname=accountname, hashtags=hashtags)
87
94
 
88
95
  ```
89
96
 
90
97
  ### Upload with TikTok Sound
91
98
 
92
99
  ```python
93
- upload_tiktok(video=video_path, description=description, sound_name='trending_sound', sound_aud_vol='main')
100
+ upload_tiktok(video=video_path, description=description, accountname=accountname, sound_name='trending_sound', sound_aud_vol='main')
94
101
  ```
95
102
 
96
103
  PLEASE READ DOCUMENTATION FOR MORE INFO.
@@ -98,7 +105,7 @@ PLEASE READ DOCUMENTATION FOR MORE INFO.
98
105
  ### Schedule an Upload
99
106
 
100
107
  ```python
101
- upload_tiktok(video=video_path, description=description, schedule='03:10', day=11)
108
+ upload_tiktok(video=video_path, description=description, accountname=accountname, schedule='03:10', day=11)
102
109
  ```
103
110
 
104
111
  PLEASE READ DOCUMENTATION FOR MORE INFO
@@ -106,16 +113,17 @@ PLEASE READ DOCUMENTATION FOR MORE INFO
106
113
  ### Perform Copyright Check Before Uploading
107
114
 
108
115
  ```python
109
- upload_tiktok(video=video_path, description=description, hashtags=hashtags, copyrightcheck=True)
116
+ upload_tiktok(video=video_path, description=description, accountname=accountname, hashtags=hashtags, copyrightcheck=True)
110
117
  ```
111
118
 
112
119
  ## 🎯 Why Choose `autotiktokuploader`?
113
120
 
114
121
  - **No more captchas:** Fully automated uploads without interruptions, If captchas do show up, no worries, they will be solved. (read documentation for more info)
115
- - **Maximize your reach:** Add popular sounds and effective hashtags that work to boost visibility.
122
+ - **Maximize your reach:** Add popular sounds and effective hashtags that work to boost visibility and go viral!
116
123
  - **Stay compliant:** Built-in copyright checks to avoid unforeseen takedowns.
117
- - **Convenient scheduling:** Post at the right time, even when you're away.
124
+ - **Convenient scheduling:** Post at the right time, even when you're away!
118
125
  - **Much faster than manually uploading:** Drastically reduce the time you need to upload videos, just click one button and be done much quicker!
126
+ - **Upload to different account:** Stay on top of all your TikTok accounts with our multi-account functionality!
119
127
 
120
128
  ## 🛠 Dependencies
121
129
 
@@ -136,4 +144,10 @@ Created by **Haziq**. Feel free to reach out at [haziqmk123@gmail.com](mailto:ha
136
144
  ## 📄 License
137
145
 
138
146
  This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details.
139
- ```
147
+
148
+ ## 📮 Related Projects
149
+
150
+ If you liked this project please check out my use case showcase project that generates TikToks and uploads them using 'tiktokautouploader'
151
+
152
+ [TikTokGenerator](https://github.com/haziq-exe/TikTokGenerator)
153
+
@@ -0,0 +1,7 @@
1
+ tiktokautouploader/__init__.py,sha256=u7OWCK_u68ST8dfrkSF4Yw44CJOzV9NXI6ASRuoDfmE,64
2
+ tiktokautouploader/function.py,sha256=m7ynv_zKtac1-wRSK2hndxevh1mUJCb0KZx8oFObz1c,44875
3
+ tiktokautouploader/Js_assets/login.js,sha256=SLhtPYo8ZfTRUnbR7Xqp084lSuAOqIWUxi75FlFH3vs,966
4
+ tiktokautouploader-3.2.dist-info/METADATA,sha256=kVxGqGPeVhibiiHayhz1KRRjMfbIyQ2yBvMAmL73zUg,6161
5
+ tiktokautouploader-3.2.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
6
+ tiktokautouploader-3.2.dist-info/licenses/LICENSE.md,sha256=hYds_VJIpnS5gC73WhuWk2IY_e9BWjuEJthQCb9ThyU,1073
7
+ tiktokautouploader-3.2.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- tiktokautouploader/__init__.py,sha256=u7OWCK_u68ST8dfrkSF4Yw44CJOzV9NXI6ASRuoDfmE,64
2
- tiktokautouploader/function.py,sha256=PhHDU2GqteX5MqsPYQiyYfT09XHbLSG3_ydH9j4QHJE,33619
3
- tiktokautouploader/Js_assets/login.js,sha256=SLhtPYo8ZfTRUnbR7Xqp084lSuAOqIWUxi75FlFH3vs,966
4
- tiktokautouploader-2.95.dist-info/METADATA,sha256=5fJDsAptfF53htSHKekKk8JGcoWdrS58LS-sucWOj30,5033
5
- tiktokautouploader-2.95.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
6
- tiktokautouploader-2.95.dist-info/licenses/LICENSE.md,sha256=hYds_VJIpnS5gC73WhuWk2IY_e9BWjuEJthQCb9ThyU,1073
7
- tiktokautouploader-2.95.dist-info/RECORD,,