skip to Main Content

I’m trying to upload video to Twitter using API and tmhOAuth for requests however I’m getting an error from Twitter: “Segments do not add up to provided total file size.”.

I checked chunks sizes with size provided in INIT command they are equal. Could you please help me find solution?

Here is a solution which I used as a basis

Here is my code:

/**
 * @param string $pathToVideo
 *
 * @return string
 *
 * @throws UploadException
 * @throws RuntimeException
 */
public function uploadVideo($pathToVideo)
{
    //execute upload init and get media ID form init command
    $mediaId = $this->init($pathToVideo);

    //uploading video
    $this->append($pathToVideo, $mediaId);

    //finalize uploading
    $code = $this->finalize($mediaId);
}


/**
 * @param string $mediaId
 *
 * @return int
 */
private function finalize($mediaId)
{
    return $this->sendPostRequest(['command'  => 'FINALIZE', 'media_id' => $mediaId]);
}

/**
 * @param string $pathToVideo
 * @param string $mediaId
 *
 * @throws UploadException
 */
private function append($pathToVideo, $mediaId)
{
    //read video file
    $fp = fopen($pathToVideo, 'r');
    //segment counter
    $segmentId = 0;
    $uploadedBytes = 0;

    while (! feof($fp)) {
        $chunk = fread($fp, self::CHUNK_LIMIT);
        $uploadedBytes += strlen($chunk);
        $code = $this->sendPostRequest([
            'command'       => 'APPEND',
            'media_id'      => $mediaId,
            'media'         => $chunk,
            'segment_index' => $segmentId,
        ], true);

        if (!in_array($code, [Response::HTTP_CONTINUE, Response::HTTP_NO_CONTENT], true)) {
            throw new UploadException(sprintf(
                "Uploading Twitter video failed during APPEND. Returned code %d.nPath to video %s.nResponse: %s",
                $code,
                $pathToVideo,
                $this->tmhOAuth->response['response']
            ));
        }

        $segmentId++;
    }

    fclose($fp);
}

/**
 * @param string $pathToVideo
 *
 * @return string
 *
 * @throws UploadException
 */
private function init($pathToVideo)
{
    $fileSize = filesize($pathToVideo);
    $code = $this->sendPostRequest([
        'command'     => 'INIT',
        'total_bytes' => $fileSize,
        'media_type'  => 'video/mp4',
    ]);

    $response = $this->tmhOAuth->response['response'];

    if ($this->isSuccessCode($code)) {
        //return media ID form init command
        return json_decode($response)->media_id_string;
    }

    throw new UploadException(sprintf(
        "Uploading Twitter video failed during INIT. Returned code %d.
        Path to video %s, file size %d.nEndpoint: " . $this->uploadUrl . "nResponse %s",
        $code,
        $pathToVideo,
        $fileSize,
        $response
    ));
}

/**
 * @param array $options
 *
 * @return int
 */
private function sendPostRequest($options, $isMultipart = false)
{
    return $this->tmhOAuth->request(
        'POST',
        $this->uploadUrl,
        $options,
        true,
        $isMultipart
    );
}

2

Answers


  1. Chosen as BEST ANSWER

    I found solution. When I set CHUNK_LIMIT to 25000 it start working. I tried to use 50000 but it was fail at the end.


  2. Twitter stated here, the limit for a chunk is 5MB. Somehow, when we limit the chunk to 5MB, the upload will fail. From my calculation, use 2MB of size for CHUNK_LIMIT is enough to upload video up to 512MB.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search