Search code examples
c#twittertweetinvi

Cannot post a video to Twitter using Tweetinvi


I am trying to post a video to Twitter using Tweetinvi library:

byte[] video = DownloadBlobFromUrl(parameters.VideoUrl);
IMedia media = Upload.ChunkUploadBinary(new UploadQueryParameters { Binaries = new List<byte[]> { video }, MediaType = "video/mp4", MediaCategory = "tweet_video", MaxChunkSize = VIDEO_MB_CHUNK_SIZE * 1024 * 1024 });
publishParameters.Medias = new List<IMedia> { media };
ITweet tweet = Tweet.PublishTweet(message, publishParameters);

The problem is that publishing fails, unless I add, before publishing, some sort of sleep, like:

await Task.Delay(25000);

With delay it works. Interesting is the fact that IMedia's member HasBeenUploaded is set to true. I also tried using chunk upload, but with the same result. How can I wait until video is fully uploaded to Twitter, assuming this is the issue?


Solution

  • I am the developer of Tweetinvi.

    The problem you are encountering is a problem of the Twitter UPLOAD API. The problem is that when an upload completes it takes between few milliseconds up to 1 second for their upload service to process it and make it available to you.

    From there you have 2 solutions.

    Solution 1 (simplicity)

    Don't specify the MediaCategory and use the classical Upload as followed:

    var videoBinary = File.ReadAllBytes("file_path");
    var videoMedia = Upload.UploadVideo(videoBinary);
    
    Tweet.PublishTweet("test", new PublishTweetOptionalParameters()
    {
        Medias = { videoMedia }
    });
    

    This video should be available straight away. But I have experienced times when a delay is required. Therefore I usually add a delay of 500ms for Twitter servers to be ready for the incoming Tweet.

    Solution 2 (amplify_video)

    amplify_video is a more robust solution as it is the solution provided by Twitter to solve the delay problem.

    var videoBinary = File.ReadAllBytes(@"C:\Users\linvi\Pictures\mov_bbb.mp4");
    var videoMedia = Upload.UploadVideo(videoBinary, "video/mp4", "amplify_video");
    
    var isProcessed = videoMedia.UploadedMediaInfo.ProcessingInfo.State == "succeeded";
    var timeToWait = videoMedia.UploadedMediaInfo.ProcessingInfo.CheckAfterInMilliseconds;
    
    while (!isProcessed)
    {
        Thread.Sleep(timeToWait);
    
        // The second parameter (false) informs Tweetinvi that you are manually awaiting the media to be ready
        var mediaStatus = Upload.GetMediaStatus(videoMedia, false);
        isProcessed = mediaStatus.ProcessingInfo.State == "succeeded";
        timeToWait = mediaStatus.ProcessingInfo.CheckAfterInMilliseconds;
    }
    

    I realize that this is complicated but few people uses amplify_video. In the next release I will add a new method that will do all this logic automatically for you.

    If you want to be informed when this feature is released you can find the work item here : https://github.com/linvi/tweetinvi/issues/347.

    I will also provide a new enum for ProcessingInfo.State (https://github.com/linvi/tweetinvi/issues/348).

    I hope this answer helps you. Have a great day.