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
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.
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.