wkaisertexas / tiktok-uploader

Automatically ⬆️ upload TikTok videos
https://pypi.org/project/tiktok-uploader/
MIT License
399 stars 90 forks source link

Failed to Upload Video with tiktok-uploader #175

Open dam2452 opened 1 month ago

dam2452 commented 1 month ago

I'm using the tiktok-uploader library and encountered an issue while trying to upload a video. The login seems to work correctly, as I can see the upload page when running with headless=False. However, the script gets stuck on the upload page for a few seconds and then throws the following error:

$ tiktok-uploader -v video.mp4 -d "lololo w" -c /mnt/c/Users/dam2452/Downloads/cookies.txt
[15:58:29] Authenticating browser with cookies
[15:58:29] Create a chrome browser instance in headless mode
[15:58:30] Authenticating browser with cookies
[15:58:32] Posting video.mp4
               with description: lololo w
[15:58:32] Navigating to upload page
[15:59:34] Failed to upload /mnt/c/GIT_REPO/tiktak-generator/video.mp4
[15:59:34] Message: 
Stacktrace:
#0 0x5562a353c02a <unknown>
#1 0x5562a32225e0 <unknown>
#2 0x5562a3271be8 <unknown>
#3 0x5562a3271e81 <unknown>
#4 0x5562a32b88c4 <unknown>
#5 0x5562a3296b4d <unknown>
#6 0x5562a32b5d7d <unknown>
#7 0x5562a32968c3 <unknown>
#8 0x5562a32646b3 <unknown>
#9 0x5562a326568e <unknown>
#10 0x5562a3506a2b <unknown>
#11 0x5562a350a9b1 <unknown>
#12 0x5562a34f3225 <unknown>
#13 0x5562a350b532 <unknown>
#14 0x5562a34d838f <unknown>
#15 0x5562a352af28 <unknown>
#16 0x5562a352b0f3 <unknown>
#17 0x5562a353ae7c <unknown>
#18 0x7f91e8068dab <unknown>

-------------------------
Error while uploading video
-------------------------
dam2452 commented 1 month ago

When running the same command on Windows, I get a slightly different outcome. The login still works, and the upload page is reached, but the video fails to upload with a different error message. Here's the output:

PS C:\GIT_REPO\tiktak-generator> tiktok-uploader -v video.mp4 -d "lololo w" -c C:\Users\dam2452\Downloads\cookies.txt
[16:17:54] Authenticating browser with cookies
[16:17:54] Create a chrome browser instance in headless mode

DevTools listening on ws://127.0.0.1:56982/devtools/browser/7fe12260-b8c3-49eb-bf93-f02a7521854e
[16:17:58] Authenticating browser with cookies
[16:18:00] Posting video.mp4
               with description: lololo w
[16:18:00] Navigating to upload page
 [INFO] [DSH]  chrome.exe
 [INFO] [DSH]  Creating WndMsg Listener Window
 [INFO] [DSH]  Get number of capabilities
 [INFO] [DSH]  Get stream caps: 0
 [INFO] [DSH]  Get stream caps: 1
 [INFO] [DSH]  Get stream caps: 2
 [INFO] [DSH]  Get stream caps: 3
 [INFO] [DSH]  Get stream caps: 4
 [INFO] [DSH]  Get stream caps: 5
 [INFO] [DSH]  Get stream caps: 6
 [INFO] [DSH]  Get stream caps: 7
 [INFO] [DSH]  Get stream caps: 8
 [INFO] [DSH]  Get stream caps: 9
 [INFO] [DSH]  Get stream caps: 10
 [INFO] [DSH]  Destroying parent object
 [INFO] [DSH]  Destroying WndMsg Listener Window
 [INFO] [DSH]  Destroyed window
 [INFO] [DSH]  Unregistered window class
[30468:32556:1008/161802.340:ERROR:socket_manager.cc(147)] Failed to resolve address for stun.l.google.com., errorcode: -105
[30468:32556:1008/161802.737:ERROR:socket_manager.cc(147)] Failed to resolve address for stun.l.google.com., errorcode: -105
[30468:32556:1008/161802.816:ERROR:socket_manager.cc(147)] Failed to resolve address for stun.l.google.com., errorcode: -105
Created TensorFlow Lite XNNPACK delegate for CPU.
Attempting to use a delegate that only supports static-sized tensors with a graph that has dynamic-sized tensors (tensor#58 is a dynamic-sized tensor).
[16:19:01] Failed to upload C:\GIT_REPO\tiktak-generator\video.mp4
[16:19:01] Message:
Stacktrace:
        GetHandleVerifier [0x00857143+25587]
        (No symbol) [0x007EA2E4]
        (No symbol) [0x006E2113]
        (No symbol) [0x00726F62]
        (No symbol) [0x007271AB]
        (No symbol) [0x00767852]
        (No symbol) [0x0074ABE4]
        (No symbol) [0x00765370]
        (No symbol) [0x0074A936]
        (No symbol) [0x0071BA73]
        (No symbol) [0x0071C4CD]
        GetHandleVerifier [0x00B34C63+3030803]
        GetHandleVerifier [0x00B86B99+3366473]
        GetHandleVerifier [0x008E95F2+624802]
        GetHandleVerifier [0x008F0E6C+655644]
        (No symbol) [0x007F2C9D]
        (No symbol) [0x007EFD68]
        (No symbol) [0x007EFF05]
        (No symbol) [0x007E2336]
        BaseThreadInitThunk [0x762B7BA9+25]
        RtlInitializeExceptionChain [0x7750C0CB+107]
        RtlClearBits [0x7750C04F+191]

-------------------------
Error while uploading video
-------------------------
PS C:\GIT_REPO\tiktak-generator> 
deniz361 commented 1 month ago

i get the same error, using chrome on Mac OS. It seems like it can't locate the iframe in the function "_change_to_upload_iframe"

Fares-Tabet commented 1 month ago

I am also getting a similar error, in which it gets stuck right after Navigating to upload page (im on Mac OS). It is able to open the upload page successfully while being logged in (https://www.tiktok.com/tiktokstudio/upload?lang=en) right before timing out and throwing the error. Could this be because the UI of the uploads page changed since the latest release ?

[23:44:35] Authenticating browser with cookies
[23:44:35] Create a chrome browser instance 
[23:44:36] Authenticating browser with cookies
[23:44:37] Posting /Users/farestabet/Downloads/test.mp4
               with description: this is my description
[23:44:37] Navigating to upload page
[23:45:39] Failed to upload /Users/farestabet/Downloads/test.mp4
[23:45:39] Message: 
Stacktrace:
0   chromedriver                        0x0000000102870500 cxxbridge1$str$ptr + 1917112
1   chromedriver                        0x0000000102868890 cxxbridge1$str$ptr + 1885256
2   chromedriver                        0x0000000102478538 cxxbridge1$string$len + 89424
3   chromedriver                        0x00000001024bc878 cxxbridge1$string$len + 368784
4   chromedriver                        0x00000001024f6b7c cxxbridge1$string$len + 607124
5   chromedriver                        0x00000001024b1374 cxxbridge1$string$len + 322444
6   chromedriver                        0x00000001024b1fc4 cxxbridge1$string$len + 325596
7   chromedriver                        0x0000000102837d2c cxxbridge1$str$ptr + 1685732
8   chromedriver                        0x000000010283c530 cxxbridge1$str$ptr + 1704168
9   chromedriver                        0x000000010281ce08 cxxbridge1$str$ptr + 1575360
10  chromedriver                        0x000000010283ce00 cxxbridge1$str$ptr + 1706424
11  chromedriver                        0x000000010280df94 cxxbridge1$str$ptr + 1514316
12  chromedriver                        0x000000010285962c cxxbridge1$str$ptr + 1823204
13  chromedriver                        0x00000001028597ac cxxbridge1$str$ptr + 1823588
14  chromedriver                        0x0000000102868530 cxxbridge1$str$ptr + 1884392
15  libsystem_pthread.dylib             0x000000018f7edf94 _pthread_start + 136
16  libsystem_pthread.dylib             0x000000018f7e8d34 thread_start + 8
jensfr1 commented 1 month ago

I do get a similar issue. tiktok-uploader -v final_video_001.mp4 -d "this is my escaped \"description\"" -c cookies.txt [09:47:51] Authenticating browser with cookies [09:47:51] Create a chrome browser instance in headless mode

DevTools listening on ws://127.0.0.1:59007/devtools/browser/1b51d308-b53d-426c-9c25-cc047fc320ed [09:47:56] Authenticating browser with cookies [09:47:58] Posting final_video_001.mp4 with description: this is my escaped "description" [09:47:58] Navigating to upload page [33052:20308:1014/094800.655:ERROR:socket_manager.cc(147)] Failed to resolve address for stun.l.google.com., errorcode: -105 [33052:20308:1014/094800.900:ERROR:socket_manager.cc(147)] Failed to resolve address for stun.l.google.com., errorcode: -105 [33052:20308:1014/094801.039:ERROR:socket_manager.cc(147)] Failed to resolve address for stun.l.google.com., errorcode: -105 Created TensorFlow Lite XNNPACK delegate for CPU. Attempting to use a delegate that only supports static-sized tensors with a graph that has dynamic-sized tensors (tensor#58 is a dynamic-sized tensor). [09:48:59] Failed to upload C:\Users\Jens\OneDrive\Desktop\amazonvideo\final_video_001.mp4 [09:48:59] Message: Stacktrace: GetHandleVerifier [0x00475523+24195] (No symbol) [0x0040AA04] (No symbol) [0x00302093] (No symbol) [0x00346ED2] (No symbol) [0x0034711B] (No symbol) [0x003876F2] (No symbol) [0x0036AB84] (No symbol) [0x00385280] (No symbol) [0x0036A8D6] (No symbol) [0x0033BA27] (No symbol) [0x0033C43D] GetHandleVerifier [0x0073CE13+2938739] GetHandleVerifier [0x0078EC69+3274185] GetHandleVerifier [0x005009C2+594722] GetHandleVerifier [0x00507EDC+624700] (No symbol) [0x004137CD] (No symbol) [0x00410528] (No symbol) [0x004106C5] (No symbol) [0x00402CA6] BaseThreadInitThunk [0x77177BA9+25] RtlInitializeExceptionChain [0x774FC0CB+107] RtlClearBits [0x774FC04F+191]


Error while uploading video

AnthonyClemens commented 1 month ago

I have a similar issue as well running on Linux: [16:19:05] Authenticating browser with cookies [16:19:05] Create a chrome browser instance in headless mode [16:19:08] Authenticating browser with cookies [16:19:11] Posting 0.mp4 with description: #2024 #reddit #redditstories #AI #storytime #redditreadings #askreddit #AITA #fyp #ViralStories #TrendingTales #DailyStories #FascinatingStories #USA [16:19:11] Navigating to upload page [16:20:14] Failed to upload /home/anthony/AutoPost/0.mp4 [16:20:14] Message: Stacktrace:

0 0x55b17c818b9a

1 0x55b17c4fe670

2 0x55b17c54dc48

3 0x55b17c54dee1

4 0x55b17c594924

5 0x55b17c572bad

6 0x55b17c591dd6

7 0x55b17c572923

8 0x55b17c5406e7

9 0x55b17c5416de

10 0x55b17c7e266b

11 0x55b17c7e6611

12 0x55b17c7ce4e5

13 0x55b17c7e7192

14 0x55b17c7b36ef

15 0x55b17c8079d8

16 0x55b17c807ba7

17 0x55b17c8179ec

18 0x7ff1b8970ac3

henrik392 commented 4 weeks ago

Same issue on MacOS: [18:35:05] Authenticating browser with cookies [18:35:05] Create a chrome browser instance [18:35:07] Authenticating browser with cookies [18:35:08] Posting ./output/video.mp4 [18:35:08] Navigating to upload page [18:36:10] Failed to upload /Users/henrikkvamme/development/cogito/HypeAI/video_automator/output/video.mp4 [18:36:10] Message: Stacktrace: 0 chromedriver 0x0000000100c77634 cxxbridge1$str$ptr + 3645404 1 chromedriver 0x0000000100c6fe94 cxxbridge1$str$ptr + 3614780 2 chromedriver 0x00000001006dc104 cxxbridge1$string$len + 88416 3 chromedriver 0x000000010071e364 cxxbridge1$string$len + 359360 4 chromedriver 0x0000000100757bd0 cxxbridge1$string$len + 594988 5 chromedriver 0x0000000100712f54 cxxbridge1$string$len + 313264 6 chromedriver 0x0000000100713ba4 cxxbridge1$string$len + 316416 7 chromedriver 0x0000000100c421d4 cxxbridge1$str$ptr + 3427196 8 chromedriver 0x0000000100c45518 cxxbridge1$str$ptr + 3440320 9 chromedriver 0x0000000100c295f8 cxxbridge1$str$ptr + 3325856 10 chromedriver 0x0000000100c45ddc cxxbridge1$str$ptr + 3442564 11 chromedriver 0x0000000100c1a87c cxxbridge1$str$ptr + 3265060 12 chromedriver 0x0000000100c60884 cxxbridge1$str$ptr + 3551788 13 chromedriver 0x0000000100c60a00 cxxbridge1$str$ptr + 3552168 14 chromedriver 0x0000000100c6fb2c cxxbridge1$str$ptr + 3613908 15 libsystem_pthread.dylib 0x00000001896af2e4 _pthread_start + 136 16 libsystem_pthread.dylib 0x00000001896aa0fc thread_start + 8

PNP-MA commented 3 weeks ago

issues is that cant find selector xpath //iframe, on upload page

DEBUG:selenium.webdriver.remote.remote_connection:POST http://localhost:58517/session/2bbc6621d2ec1d746381072dff5a960e/element {'using': 'xpath', 'value': '//iframe'} DEBUG:selenium.webdriver.remote.remote_connection:Remote response: status=404 | data={"value":{"error":"no such element","message":"no such element: Unable to locate element: {\"method\":\"xpath\",\"selector\":\"//iframe\"}\n (Session info: chrome=130.0.6723.91)","stacktrace":"#0 0x5f9444a6113a \u003Cunknown>\n#1 0x5f944457c460 \u003Cunknown>\n#2 0x5f94445c8f96 \u003Cunknown>\n#3 0x5f94445c9221 \u003Cunknown>\n#4 0x5f944460e5d4 \u003Cunknown>\n#5 0x5f94445ed03d \u003Cunknown>\n#6 0x5f944460baf6 \u003Cunknown>\n#7 0x5f94445ecdb3 \u003Cunknown>\n#8 0x5f94445bbc10 \u003Cunknown>\n#9 0x5f94445bcbee \u003Cunknown>\n#10 0x5f9444a2d3cb \u003Cunknown>\n#11 0x5f9444a31368 \u003Cunknown>\n#12 0x5f9444a1aeec \u003Cunknown>\n#13 0x5f9444a31ee7 \u003Cunknown>\n#14 0x5f9444a0013f \u003Cunknown>\n#15 0x5f9444a4f858 \u003Cunknown>\n#16 0x5f9444a4fa20 \u003Cunknown>\n#17 0x5f9444a5ffb6 \u003Cunknown>\n#18 0x76f311ea1e2e \u003Cunknown>\n#19 0x76f311f33a4c \u003Cunknown>\n"}} | headers=HTTPHeaderDict({'Content-Length': '887', 'Content-Type': 'application/json; charset=utf-8', 'cache-control': 'no-cache'}) DEBUG:selenium.webdriver.remote.remote_connection:Finished Request

ryandikdan commented 3 weeks ago

I had the same issue and it seems that tiktok changed their website to remove an iframe that was previously there. I had claude help me out. Maybe some of you can benefit as well. I tried to add settings under the See More panel, but that didn't work. Everything is shown below:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import time
import http.cookiejar
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

def set_advanced_options(driver):
    """Handle the advanced options including AI-generated content setting"""
    print("Setting advanced options...")

    try:
        # Click "See more" to expand advanced settings
        see_more_selector = "[data-e2e='advanced_settings_container'] .more-btn"
        see_more_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, see_more_selector))
        )
        see_more_button.click()
        time.sleep(1)  # Wait for animation

        # Find and click the AI-generated content switch
        ai_switch_selector = "[data-e2e='aigc_container'] input[type='checkbox']"
        ai_switch = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, ai_switch_selector))
        )

        # Check if it's already enabled
        if not ai_switch.is_selected():
            # Try different click methods
            try:
                # Try direct click first
                ai_switch.click()
            except:
                try:
                    # Try clicking the parent container
                    driver.execute_script("arguments[0].closest('.TUXSwitch').click();", ai_switch)
                except:
                    # Try JavaScript click on the input
                    driver.execute_script("arguments[0].click();", ai_switch)

        print("Advanced options set successfully")
        return True

    except Exception as e:
        print(f"Error setting advanced options: {str(e)}")
        return False

def parse_cookies_txt(cookies_path):
    """Parse cookies.txt file and return a list of cookie dictionaries"""
    cookie_jar = http.cookiejar.MozillaCookieJar(cookies_path)
    cookie_jar.load(ignore_discard=True, ignore_expires=True)

    cookies = []
    for cookie in cookie_jar:
        cookie_dict = {
            'name': cookie.name,
            'value': cookie.value,
            'domain': cookie.domain,
            'path': cookie.path,
        }
        if cookie.secure:
            cookie_dict['secure'] = cookie.secure
        if cookie.expires:
            cookie_dict['expiry'] = cookie.expires

        cookies.append(cookie_dict)

    return cookies

def click_post_button(driver):
    """Enhanced function to find and click the specific TikTok post button"""
    print("Attempting to click post button...")

    # Wait for any loading/processing to complete
    time.sleep(2)

    try:
        # First try finding by exact class name
        button_selectors = [
            "button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary",
            "[data-e2e='post_video_button']",
            "button[data-e2e='post_video_button']",
            "button.TUXButton"
        ]

        post_button = None
        for selector in button_selectors:
            try:
                post_button = WebDriverWait(driver, 5).until(
                    EC.element_to_be_clickable((By.CSS_SELECTOR, selector))
                )
                if post_button and post_button.is_displayed() and post_button.get_attribute('aria-disabled') != 'true':
                    break
            except:
                continue

        if not post_button:
            # Fallback to find by XPath with specific text
            try:
                post_button = WebDriverWait(driver, 5).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, "//button[.//div[contains(text(), 'Post')]]")
                    )
                )
            except:
                print("Could not find post button by text content")

        if post_button:
            print("Found post button, attempting to click...")

            # Scroll the button into view
            driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", post_button)
            time.sleep(1)

            # Try multiple click methods
            click_methods = [
                # Method 1: Direct click
                lambda: post_button.click(),

                # Method 2: JavaScript click
                lambda: driver.execute_script("arguments[0].click();", post_button),

                # Method 3: JavaScript click with focus
                lambda: driver.execute_script("""
                    arguments[0].focus();
                    arguments[0].click();
                """, post_button),

                # Method 4: ActionChains click
                lambda: ActionChains(driver).move_to_element(post_button).click().perform(),

                # Method 5: JavaScript dispatch click event
                lambda: driver.execute_script("""
                    var event = new MouseEvent('click', {
                        view: window,
                        bubbles: true,
                        cancelable: true
                    });
                    arguments[0].dispatchEvent(event);
                """, post_button),
            ]

            # Try each click method until one works
            for i, click_method in enumerate(click_methods, 1):
                try:
                    click_method()
                    print(f"Successfully clicked post button using method {i}")

                    # Wait for upload confirmation
                    confirmation_texts = [
                        "Your video is being uploaded",
                        "Video posted",
                        "Upload successful",
                        "Processing your video",
                        "Your video has been uploaded"
                    ]

                    xpath_conditions = [
                        f"//div[contains(text(), '{text}')]" for text in confirmation_texts
                    ]

                    try:
                        upload_complete = WebDriverWait(driver, max_wait).until(
                            EC.presence_of_element_located((
                                By.XPATH, 
                                "//span[contains(@class, 'TUXText') and contains(@class, 'TUXText--tiktok-sans') and text()='Uploaded']"
                            ))
                        )
                        print("Upload confirmed successful!")
                        return True
                    except TimeoutException:
                        print("Warning: Click seemed to work but couldn't confirm upload status")
                        continue

                except Exception as e:
                    print(f"Click method {i} failed: {str(e)}")
                    continue

            print("All click methods attempted")
            return False
        else:
            print("Error: Post button not found")
            return False

    except Exception as e:
        print(f"Error during post button click: {str(e)}")
        return False

def clear_input(element):
    """Clear input field properly"""
    element.send_keys(Keys.CONTROL + "a")  # Select all
    element.send_keys(Keys.DELETE)         # Delete selection

def upload_to_tiktok(video_path, cookies_path, description="", browser_type="chrome"):
    """Upload a video to TikTok using saved cookies from a cookies.txt file"""

    if browser_type.lower() == "chrome":
        from selenium.webdriver.chrome.options import Options
        options = Options()
        options.add_argument("--disable-blink-features=AutomationControlled")
        options.add_experimental_option("excludeSwitches", ["enable-automation"])
        options.add_experimental_option('useAutomationExtension', False)
        driver = webdriver.Chrome(options=options)
    else:
        from selenium.webdriver.firefox.options import Options
        options = Options()
        driver = webdriver.Firefox(options=options)

    try:
        print("Loading TikTok...")
        driver.get("https://www.tiktok.com")

        print("Setting cookies...")
        cookies = parse_cookies_txt(cookies_path)
        for cookie in cookies:
            try:
                driver.add_cookie(cookie)
            except Exception as e:
                print(f"Warning: Couldn't set cookie {cookie.get('name')}: {str(e)}")
                continue

        driver.refresh()
        time.sleep(2)

        print("Navigating to upload page...")
        driver.get("https://www.tiktok.com/creator#/upload")
        time.sleep(3)

        try:
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='file']"))
            )
        except TimeoutException:
            raise Exception("Login failed - please check your cookies file")

        print("Uploading video...")
        file_input = WebDriverWait(driver, 20).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='file']"))
        )
        file_input.send_keys(video_path)

        print("Waiting for processing...")
        try:
            WebDriverWait(driver, 60).until(
                EC.any_of(
                    EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'Processing complete')]")),
                    EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'Upload complete')]")),
                    EC.presence_of_element_located((By.XPATH, "//div[contains(text(), 'Uploaded')]"))
                )
            )
        except TimeoutException:
            print("Warning: Couldn't confirm upload completion, but continuing...")

        # Enhanced description setting
        if description:
            print("Setting description...")
            time.sleep(2)  # Wait for any auto-filled caption to appear

            try:
                # Try multiple ways to find the caption input
                caption_selectors = [
                    (By.CSS_SELECTOR, "div[class*='public-DraftEditor-content']"),
                    (By.CSS_SELECTOR, "div[class*='DraftEditor-root']"),
                    (By.XPATH, "//div[@contenteditable='true']"),
                    (By.XPATH, "//div[@role='textbox']")
                ]

                caption_input = None
                for by, selector in caption_selectors:
                    try:
                        caption_input = WebDriverWait(driver, 5).until(
                            EC.presence_of_element_located((by, selector))
                        )
                        if caption_input.is_displayed() and caption_input.is_enabled():
                            break
                    except:
                        continue

                if caption_input:
                    # Clear existing text
                    actions = ActionChains(driver)
                    actions.click(caption_input).perform()
                    time.sleep(1)

                    # Select all existing text and delete it
                    actions.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform()
                    actions.send_keys(Keys.DELETE).perform()
                    time.sleep(1)

                    # Type new description
                    actions.send_keys(description).perform()
                else:
                    print("Warning: Couldn't find caption input")

            except Exception as e:
                print(f"Warning: Couldn't set description: {str(e)}")

        # Set advanced settings like AI generated checkbox
        if not set_advanced_options(driver):
            print("Warning: Could not set advanced options")

        # Enhanced post button clicking
        print("Posting video...")
        time.sleep(2)  # Wait for any animations

        success = click_post_button(driver)

        if not success:
            print("Failed to post video. Keeping browser open for debugging...")
        else:
            print("Video posted successfully!")
            time.sleep(5)  # Wait to see final status

        driver.quit()

    except Exception as e:
        print(f"Error: {str(e)}")

    finally:
        driver.quit()

if __name__ == "__main__":
    # Example usage:
    cookie = 'C:/Users/Ryan/Downloads/cookies.txt'
    video_path = "C:/Users/Ryan/Videos/mtg_llm/test_short.mp4"
    title = "test"
    description = "test vid #fyp"
    upload_to_tiktok(video_path, cookie, description)
PNP-MA commented 3 weeks ago

here is fixed version that i just fix : https://github.com/G6KG/tiktok-uploader

mafr0n commented 1 week ago

here is fixed version that i just fix : https://github.com/G6KG/tiktok-uploader

How I can use it? When I tried to build and import package with hatch submodules like tiktok_uploader.auth didn't work.

PNP-MA commented 1 week ago

show us your example code and errors

mafr0n commented 1 week ago

show us your example code and errors

image

main.py:

import os
from upload import upload_videos
from tiktok_uploader.auth import AuthBackend

from selenium.webdriver.chrome.options import Options

def main():
    videos_dir = './videos'
    videos_to_upload = []

    for filename in os.listdir(videos_dir):
        if filename.endswith('.mp4'):
            video_path = os.path.join(videos_dir, filename)
            video_name = os.path.splitext(filename)[0]
            description = f'{video_name}'
            video = {'path': video_path, 'description': description}
            videos_to_upload.append(video)

    if not videos_to_upload:
        print("No videos found in ./videos directory.")
        return

    auth = AuthBackend(cookies='cookies.txt')
    options = Options()
    options.add_argument('--headless')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')

    failed_videos = upload_videos(videos=videos_to_upload, auth=auth, options=options)

    if failed_videos:
        print("Failed to upload the following videos:")
        for video in failed_videos:
            print(f"- {video['path']} with description: {video['description']}")
    else:
        print("All videos uploaded successfully.")

if __name__ == '__main__':
    main()

upload.py I just copied from your repository

log:

DevTools listening on ws://127.0.0.1:53313/devtools/browser/3f5bafb0-be05-4583-a8cd-11d003722eed
[16:00:24] Authenticating browser with cookies
[16:00:40] Posting ./videos\1.mp4
               with description: 1
[16:00:40] Navigating to upload page
[16:01:08] Uploading video file
[6752:8752:1117/160116.895:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
[6752:8752:1117/160118.750:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
[6752:8752:1117/160118.810:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
[6752:8752:1117/160118.997:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
[6752:8752:1117/160124.876:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
[6752:8752:1117/160124.884:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
[6752:8752:1117/160125.350:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
[6752:8752:1117/160125.351:ERROR:ffmpeg_common.cc(970)] Unsupported pixel format: -1
Created TensorFlow Lite XNNPACK delegate for CPU.
[6752:760:1117/160146.045:ERROR:stun_port.cc(101)] Binding request timed out from [0:0:0:x:x:x:x:x]:60948 (any)
[6752:760:1117/160155.814:ERROR:stun_port.cc(101)] Binding request timed out from [0:0:0:x:x:x:x:x]:62596 (any)
[6752:760:1117/160158.076:ERROR:stun_port.cc(101)] Binding request timed out from [0:0:0:x:x:x:x:x]:62015 (any)
Attempting to use a delegate that only supports static-sized tensors with a graph that has dynamic-sized tensors (tensor#58 is a dynamic-sized tensor).
TimeoutException occurred:
 Message:
Stacktrace:
        GetHandleVerifier [0x010FEBD3+24307]
        (No symbol) [0x01088D74]
        (No symbol) [0x00F6C323]
        (No symbol) [0x00FADC86]
        (No symbol) [0x00FADECB]
        (No symbol) [0x00FEB9F2]
        (No symbol) [0x00FCFED4]
        (No symbol) [0x00FE9579]
        (No symbol) [0x00FCFC26]
        (No symbol) [0x00FA219C]
        (No symbol) [0x00FA311D]
        GetHandleVerifier [0x013A8D93+2818227]
        GetHandleVerifier [0x0140542E+3196750]
        GetHandleVerifier [0x013FD9D2+3165426]
        GetHandleVerifier [0x0119DA70+675216]
        (No symbol) [0x01091B3D]
        (No symbol) [0x0108EA18]
        (No symbol) [0x0108EBB5]
        (No symbol) [0x01081640]
        BaseThreadInitThunk [0x76C9FA29+25]
        RtlGetAppContainerNamedObjectPath [0x77D67A9E+286]
        RtlGetAppContainerNamedObjectPath [0x77D67A6E+238]

[16:02:21] Removing split window
[16:02:26] Split window not found or operation timed out
[16:02:26] Setting interactivity settings
[16:02:31] Failed to set interactivity settings
[16:02:31] Setting description
[16:02:32] Failed to upload C:\Users\arder\Downloads\fgfghgh\videos\1.mp4
[16:02:32] Message: element click intercepted: Element <div aria-autocomplete="list" aria-expanded="false" class="notranslate public-DraftEditor-content" contenteditable="true" role="combobox" spellcheck="false" style="outline: none; user-select: text; white-space: pre-wrap; overflow-wrap: break-word;">...</div> is not clickable at point (605, 330). Other element would receive the click: <div class="jsx-1540291114 common-modal-body">...</div>
  (Session info: chrome=130.0.6723.119)
Stacktrace:
        GetHandleVerifier [0x010FEBD3+24307]
        (No symbol) [0x01088D74]
        (No symbol) [0x00F6C323]
        (No symbol) [0x00FB3B07]
        (No symbol) [0x00FB1F79]
        (No symbol) [0x00FAFE64]
        (No symbol) [0x00FAF45E]
        (No symbol) [0x00FA415D]
        (No symbol) [0x00FCFE8C]
        (No symbol) [0x00FA3C14]
        (No symbol) [0x00FD0124]
        (No symbol) [0x00FE9579]
        (No symbol) [0x00FCFC26]
        (No symbol) [0x00FA219C]
        (No symbol) [0x00FA311D]
        GetHandleVerifier [0x013A8D93+2818227]
        GetHandleVerifier [0x0140542E+3196750]
        GetHandleVerifier [0x013FD9D2+3165426]
        GetHandleVerifier [0x0119DA70+675216]
        (No symbol) [0x01091B3D]
        (No symbol) [0x0108EA18]
        (No symbol) [0x0108EBB5]
        (No symbol) [0x01081640]
        BaseThreadInitThunk [0x76C9FA29+25]
        RtlGetAppContainerNamedObjectPath [0x77D67A9E+286]
        RtlGetAppContainerNamedObjectPath [0x77D67A6E+238]