最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - The total chunk count is invalid when uploading video to publish on tiktok using tiktok api in laravel - Stack Overflow

programmeradmin4浏览0评论

when publish samll videos 3mb 2mb it workes fine as long as it not chunked meaning less than 5MB and it is totalchunks var equal 1 as you can see in code below but when go to lager videos when you must chunk like 28mb it show me this error : The total chunk count is invalid

{
    "success": false,
    "error": "Failed to upload video: Client error: `POST /` resulted in a `400 Bad Request` response:\n{\"error\":{\"code\":\"invalid_params\",\"message\":\"The total chunk count is invalid\",\"log_id\":\"20250121074544981EFF65ABBF7906D (truncated...)\n",
    "publish_id": null,
    "video_size": 24700139,
    "chunks": 5,
    "chunksize": 5242880
}

this how u calculate the chunksize of a video i stored in public/videos

  // Get video from public folder
            $videoPath = public_path('videos/xyz.mp4');
            if (!file_exists($videoPath)) {
                return response()->json([
                    'success' => false,
                    'error' => 'Video file not found in public/videos folder'
                ], 404);
            }
    
            // Calculate video parameters with TikTok specs
            $videoSize = (int)filesize($videoPath);
            $minChunkSize = 5 * 1024 * 1024; // 5MB minimum
            $maxChunkSize = 64 * 1024 * 1024; // 64MB maximum
            
            // Handle small videos (<5MB)
            if ($videoSize < $minChunkSize) {
                $chunkSize = $videoSize;
                $totalChunks = 1;
            } else {
                // Calculate optimal chunk size
                $chunkSize = min($maxChunkSize, (int)ceil($videoSize / 1000));
                $chunkSize = max($minChunkSize, $chunkSize);
                $totalChunks = (int)ceil($videoSize / $chunkSize);
            }
    

and here where i init video upload to tiktok

 try {
                $client = new Client(['timeout' => 300]);
                
                // Initialize video upload
                $initResponse = $client->post('/', [
                    'headers' => [
                        'Authorization' => 'Bearer ' . $usertiktok->access_token,
                        'Content-Type' => 'application/json'
                    ],
                    'json' => [
                        'source_info' => [
                            'source' => 'FILE_UPLOAD',
                            'video_size' => $videoSize,
                            'chunk_size' => $chunkSize,
                            'total_chunk_count' => $totalChunks
                        ],
                        'post_info' => [
                            'title' => $request->title,
                            'description' => $request->description ?? '',
                            'privacy_level' => $request->privacy_level,
                            'disable_duet' => false,
                            'disable_comment' => false,
                            'disable_stitch' => false
                        ]
                    ]
                ]);
    

and that is full code

    public function uploadVideo(Request $request)
        {
            $account_id = auth()->user()->account_id;
            $user_id = $request->user_id;
            
            // Get video from public folder
            $videoPath = public_path('videos/xyz.mp4');
            if (!file_exists($videoPath)) {
                return response()->json([
                    'success' => false,
                    'error' => 'Video file not found in public/videos folder'
                ], 404);
            }
    
            // Calculate video parameters with TikTok specs
            $videoSize = (int)filesize($videoPath);
            $minChunkSize = 5 * 1024 * 1024; // 5MB minimum
            $maxChunkSize = 64 * 1024 * 1024; // 64MB maximum
            
            // Handle small videos (<5MB)
            if ($videoSize < $minChunkSize) {
                $chunkSize = $videoSize;
                $totalChunks = 1;
            } else {
                // Calculate optimal chunk size
                $chunkSize = min($maxChunkSize, (int)ceil($videoSize / 1000));
                $chunkSize = max($minChunkSize, $chunkSize);
                $totalChunks = (int)ceil($videoSize / $chunkSize);
            }
    
            // Validate video size
            if ($videoSize > 4 * 1024 * 1024 * 1024) { // 4GB max
                return response()->json([
                    'success' => false,
                    'error' => 'Video size must be less than 4GB'
                ], 400);
            }
    
            // Validate chunk count
            if ($totalChunks > 1000) {
                return response()->json([
                    'success' => false,
                    'error' => 'Invalid chunk count. Must be maximum 1000'
                ], 400);
            }
    
            // Validate request
            $request->validate([
                'title' => 'required|string|max:150',
                'description' => 'nullable|string|max:2200',
                'privacy_level' => 'required|in:PUBLIC_TO_EVERYONE,MUTUAL_FOLLOW_FRIENDS,SELF_ONLY',
            ]);
    
            $usertiktok = User::where("id", $user_id)
                ->where("account_id", $account_id)
                ->where("social_type", "tiktok")
                ->first();
    
            if (!$usertiktok) {
                return response()->json(["message" => "TikTok account not found"], 400);
            }
    
            try {
                $client = new Client(['timeout' => 300]);
                
                // Initialize video upload
                $initResponse = $client->post('/', [
                    'headers' => [
                        'Authorization' => 'Bearer ' . $usertiktok->access_token,
                        'Content-Type' => 'application/json'
                    ],
                    'json' => [
                        'source_info' => [
                            'source' => 'FILE_UPLOAD',
                            'video_size' => $videoSize,
                            'chunk_size' => $chunkSize,
                            'total_chunk_count' => $totalChunks
                        ],
                        'post_info' => [
                            'title' => $request->title,
                            'description' => $request->description ?? '',
                            'privacy_level' => $request->privacy_level,
                            'disable_duet' => false,
                            'disable_comment' => false,
                            'disable_stitch' => false
                        ]
                    ]
                ]);
    
                $initData = json_decode($initResponse->getBody(), true);
                if (!isset($initData['data']['upload_url'])) {
                    throw new \Exception('Failed to get upload URL: ' . json_encode($initData));
                }
    
                $uploadUrl = $initData['data']['upload_url'];
                $publishId = $initData['data']['publish_id'];
                
                // Upload video chunks
                $videoFile = null;
                try {
                    $videoFile = fopen($videoPath, 'r');
                    if (!$videoFile) {
                        throw new \Exception('Failed to open video file');
                    }
    
                    for ($chunk = 0; $chunk < $totalChunks; $chunk++) {
                        $offset = $chunk * $chunkSize;
                        $currentChunkSize = ($chunk == $totalChunks - 1) 
                            ? ($videoSize - $offset) 
                            : $chunkSize;
                        
                        fseek($videoFile, $offset);
                        $chunkData = fread($videoFile, $currentChunkSize);
    
                        $response = $client->put($uploadUrl, [
                            'headers' => [
                                'Authorization' => 'Bearer ' . $usertiktok->access_token,
                                'Content-Type' => 'video/mp4',
                                'Content-Length' => $currentChunkSize,
                                'Content-Range' => sprintf('bytes %d-%d/%d', 
                                    $offset, 
                                    $offset + $currentChunkSize - 1,
                                    $videoSize
                                )
                            ],
                            'body' => $chunkData
                        ]);
    
                        // Check response codes (206 for partial, 201 for complete)
                        $statusCode = $response->getStatusCode();
                        if ($statusCode !== ($chunk == $totalChunks - 1 ? 201 : 206)) {
                            throw new \Exception("Unexpected response code: $statusCode");
                        }
                    }
                } finally {
                    if (is_resource($videoFile)) {
                        fclose($videoFile);
                    }
                }
    
                // Check upload status
                $maxAttempts = 30;
                $attempts = 0;
                $status = 'PROCESSING';
                
                while ($status === 'PROCESSING' && $attempts < $maxAttempts) {
                    $statusResponse = $client->post('/', [
                        'headers' => [
                            'Authorization' => 'Bearer ' . $usertiktok->access_token,
                            'Content-Type' => 'application/json'
                        ],
                        'json' => [
                            'publish_id' => $publishId
                        ]
                    ]);
    
                    $statusData = json_decode($statusResponse->getBody(), true);
                    $status = $statusData['data']['status'] ?? 'PROCESSING';
                    
                    if ($status === 'PROCESSING') {
                        sleep(2);
                        $attempts++;
                    }
                }
    
                if ($status === 'FAILED') {
                    throw new \Exception('Upload failed during processing');
                }
    
                return response()->json([
                    'success' => true,
                    'message' => 'Video uploaded successfully',
                    'data' => [
                        'publish_id' => $publishId,
                        'status' => $status,
                        'video_size' => $videoSize,
                        'chunks' => $totalChunks
                    ]
                ]);
    
            } catch (\Exception $e) {
                Log::error('TikTok Upload Error', [
                    'error' => $e->getMessage(),
                    'user_id' => $user_id,
                    'video_size' => $videoSize ?? 0,
                    'chunks' => $totalChunks ?? 0,
                    'publish_id' => $publishId ?? null
                ]);
    
                return response()->json([
                    'success' => false,
                    'error' => 'Failed to upload video: ' . $e->getMessage(),
                    'publish_id' => $publishId ?? null
                ], 500);
            }
        }

i tried to change the $totalChunks variable to be static as 1 but it give me different error

{
    "success": false,
    "error": "Failed to upload video: Client error: `POST /` resulted in a `400 Bad Request` response:\n{\"error\":{\"code\":\"invalid_params\",\"message\":\"The chunk size is invalid\",\"log_id\":\"20250120150836CF3EDDD9FB5BFC1C0A85\"}}\n",
    "publish_id": null
}

and i also tried to send the video as one chunk like small video but it give differenet error which is error during processing video .

I followed everythinge according to this documentation and still not working , pls anyone with experience with publishing with tiktok api can help? Link to tiktok docs:

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论