in Social Media

Long time guys. I don’t really have a good excuse for why, because my excuse is laziness.

Anyway, I’m currently working on a personal project that involves uploading video to twitter. I don’t want to go into more details because I might never finish it, and I really don’t want too many people asking what happened.

While I was using it to upload some video, I encountered an error that I couldn’t easily fix:

twython.exceptions.TwythonError: Twitter API returned a 400 (Bad Request), Duration too long, maximum:30000, actual:60000 (MediaId: snf:1128709657999106049)

Now if you look at the Twython documentation for uploading a status with video you’ll find the following code:

video = open('/path/to/file/video.mp4', 'rb')
response = twitter.upload_video(media=video, media_type='video/mp4')
twitter.update_status(status='Checkout this cool video!', media_ids=[response['media_id']])

As part of my efforts to debug the issue I looked at the response object:

{'media_id': 1128709657999106049, 'media_id_string': '1128709657999106049', 'size': 5117159, 'expires_after_secs': 86400, 'video': {'video_type': 'video/mp4'}}

It’s a dictionary. This told me that the video was being uploaded but the length (remember the error: Duration too long, maximum:30000, actual:60000). Reading the Twitter documentation didn’t help much as the limitations mentioned are only about size:

Size restrictions for uploading via API
– Image 5MB
– GIF 15MB
– Video 15MB

After a bit of googling, I found out that the upload that Twython does in the example given is sync (this has a duration limit of 30 seconds, and a size limit of 15 MB) while what I needed was async or what twitter changed to calling chunked media upload.

However, the Twython documentation didn’t have that documented clearly. But I did find this issue on Github that pointed me in the right direction. I simply needed to add media_category='tweet_video', check_progress=True to the upload arguments.

video = open(video_path, 'rb') response = twitter.upload_video(media=video, media_type='video/mp4', media_category='tweet_video', check_progress=True)

Be careful though of following the example from before though. Because of how the upload is done, in chunks, which can take a little time. Keep an eye on the response object contains processing_info which contains a state variable. See examples:

1. 'processing_info': {'state': 'pending', 'check_after_secs': 1}
2. 'processing_info': {'state': 'succeeded', 'progress_percent': 100}

You can only upload after the state changes to succeeded. While Twython does have it’s own way of dealing with this there were a couple of times I did get the first state. I dealt with this by adding a sleep period that matches the check_after_secs variable if it is in the response variable otherwise it moves to update the status. This is what it looked like:

processing_info = response['processing_info']
state = processing_info['state']
wait = processing_info.get('check_after_secs', 1)
if (state == 'pending' or state == 'in_progress'):
    print('Waiting ' + wait + 's')
    time.sleep(wait)

This covered any edge cases for me. I hope you found this helpful. Peace!!!