Chunked upload support?

Jun 24, 2015 at 6:21 PM
Is there chunked upload support?

https://dev.twitter.com/rest/public/uploading-media
https://dev.twitter.com/rest/reference/post/media/upload-chunked

I particularly need it for video uploads.
Or maybe of course I do something wrong :)
Coordinator
Jun 24, 2015 at 9:36 PM
Hi there,

The chunked upload endpoint is not supported but I am pretty sure I have already used the upload media to upload video.

Here are the methods available in Tweetinvi.
var binary = new byte[10];
Upload.UploadBinary(binary);
Upload.UploadBinaries(new[] { binary });
Upload.UploadMedias(new[] { new Media { Data = binary } }, true);
Please let me know if this is helping you in any way. If you really need the Chunked Upload, this will be added in the next release (0.9.9.0).

Cheers,
Linvi
Coordinator
Jun 24, 2015 at 9:43 PM
I have created a work item for this feature. (https://tweetinvi.codeplex.com/workitem/2608)

Please feel free to vote on it, if you want to get notified when this is done.
And do not forget to let me know if you need this in the next release or if the Upload feature is enough.

Linvi
Jun 24, 2015 at 9:55 PM
Ok, I checked the upload function, and how should I link the uploaded IMedia to the tweet?
Coordinator
Jun 25, 2015 at 9:52 AM
Here is a very simple example;
var binary = new byte[10];
var tweetWithMedia = Tweet.CreateTweetWithMedia("hello", binary);
tweetWithMedia.AddMedia(binary2);
var success = tweetWithMedia.Publish();
You can also add a media as a clone. This will reupload the media but it will make sure that the media has not been used for 2 publication (which is not authorized by the Twitter REST API).
var media = Upload.UploadBinary(binary);
tweetWithMedia.AddMediaAsAClone(media);
I don't remember the reason I decided to not directly authorize developers to AddMedia from a media object without cloning it. I guess I wanted to make sure the operation did not fail.

What do you think about this decision?

Cheers,
Linvi
Jun 25, 2015 at 11:31 AM
Unfortunately no luck with both of these methods. It works for pictures/gifs but not for a video.
I even tried to upload this very video:
https://blog.twitter.com/2015/rest-api-now-supports-native-video-upload
Is there some debug option, so I can see what exactly twit API doesn't like about the uploaded media?
Coordinator
Jun 25, 2015 at 11:45 AM
Hi,

I will have a look into this issue. You can get more information about the issues by working with the ExceptionHandler.
// Disable Automatic Exception Handling
ExceptionHandler.SwallowWebExceptions = false;

// If you have the exception handler is enable use the following code
var lastException = ExceptionHandler.GetLastException();
They will both return a TwitterException with loads of useful information in it.

Linvi
Jun 26, 2015 at 3:02 PM
Twitinvi.Logic.Exceptions.TwitterExceptionInfo
{"request":"\/1.1\/media\/upload.json","error":"media type unrecognized."}
Yep, I think mp4 can only be uploaded via chunked upload endpoint
Or maybe it's just twitter stuff really wants me to do it that way
Coordinator
Jun 26, 2015 at 3:23 PM
Hi,

Alright, this is a work item that will be added to Tweetinvi 0.9.9.0. But I have not yet started to work on this release, so please don't expect this feature to available from nuget before the end of July.

Though this feature should be available from the Source Code in the coming weeks. I will post a message on this post when it is available from the source code.

I am sorry for these delays, but I hope you will understand them.

Kind Regards,
Linvi
Jun 26, 2015 at 3:27 PM
Ok, I'm pretty fine with it. It's a new feature, I see no other libraries that support it for now :)
Will wait for source
Coordinator
Jun 26, 2015 at 9:02 PM
Edited Jun 27, 2015 at 1:18 PM
Hi,

If you use the latest source code of tweetinvi, you can upload using the following code.
using System;
using System.IO;
using Tweetinvi;
using Tweetinvi.Core.Enum;
using Tweetinvi.Core.Extensions;
using Tweetinvi.Core.Interfaces;
using Tweetinvi.Logic.DTO;
using Tweetinvi.Logic.Model;
using Tweetinvi.WebLogic;

namespace Examplinvi
{
    public class VideoPublisher
    {
        public static ITweet PublishTweetWithVideo(string tweetMessage, string filePath)
        {
            ExceptionHandler.SwallowWebExceptions = false;
            var binary = File.ReadAllBytes(filePath);
            var mediaType = "video/mp4";

            var media = new Media
            {
                Data = binary,
                UploadedMediaInfo = new UploadedMediaInfo()
            };

            try
            {
                // Initialize Query
                var initQuery = "https://upload.twitter.com/1.1/media/upload.json?";

                initQuery = initQuery.AddParameterToQuery("command", "INIT");
                initQuery = initQuery.AddParameterToQuery("media_type", mediaType);
                initQuery = initQuery.AddParameterToQuery("total_bytes", binary.Length.ToString());

                var mediaInfos = TwitterAccessor.ExecutePOSTQuery<InitModel>(initQuery);
                Console.WriteLine(mediaInfos.MediaId);

                // Upload Query
                var appendQuery = "https://upload.twitter.com/1.1/media/upload.json?";

                appendQuery = appendQuery.AddParameterToQuery("command", "APPEND");
                appendQuery = appendQuery.AddParameterToQuery("media_id", mediaInfos.MediaId.ToString());
                appendQuery = appendQuery.AddParameterToQuery("segment_index", "0");

                var requestGenerator = TweetinviContainer.Resolve<ITwitterRequestHandler>();
                requestGenerator.ExecuteMultipartQuery(appendQuery, "media", HttpMethod.POST, new[] {media});

                // FinalizeQuery
                var finalizeQuery = "https://upload.twitter.com/1.1/media/upload.json?";

                finalizeQuery = finalizeQuery.AddParameterToQuery("command", "FINALIZE");
                finalizeQuery = finalizeQuery.AddParameterToQuery("media_id", mediaInfos.MediaId.ToString());

                TwitterAccessor.ExecutePOSTQuery<FinalizeModel>(finalizeQuery);

                media.UploadedMediaInfo.MediaId = mediaInfos.MediaId;
                var mytweet = Tweet.CreateTweet(tweetMessage);
                mytweet.AddMedia(media);

                var success = mytweet.Publish();

                return success ? mytweet : null;
            }
            catch (Exception)
            {
                // Handle your exception
                return null;
            }
        }
    }
}
Here are the models that you will need:
public class InitModel
{
    [JsonProperty("media_id")]
    public long MediaId { get; set; }
}

public class FinalizeModel
{
    [JsonProperty("media_id")]
    public long MediaId { get; set; }

    [JsonProperty("size")]
    public long Size { get; set; }

    [JsonProperty("expires_after")]
    public long ExpiresAfter { get; set; }

    [JsonProperty("video")]
    public VideoModel Video { get; set; }
}

public class VideoModel
{
    [JsonProperty("video_type")] 
    public string VideoType { get; set; }
}
You can use the previous code as followed:
var tweetWithVideo = VideoPublisher.PublishTweetWithVideo("hello", @"C:\my_video.mp4");
Obviously this is not a final solution but it could give you a first way to publish videos on Twitter with Tweetinvi.
Marked as answer by linvi on 6/27/2015 at 12:33 PM
Coordinator
Jun 27, 2015 at 2:39 PM
Please update to Tweetinvi 0.9.8.1 to be able to use this code without having to compile the Source code.

Linvi
Jun 27, 2015 at 4:27 PM
Perfect! Everything works! :)
Well except times when twitter server bugs out, but that's their problem.
Coordinator
Jun 27, 2015 at 8:25 PM
Good, I am glad it works for you.

Please consider taking time to review tweetinvi, follow the project on codeplex or github.
This will allow you to get notified when new versions are released.

Linvi
Jul 18, 2015 at 8:35 PM
Am running some tests on this code. With files UNDER 1mb, everything runs perfect.

However, files over 1mb, it errors with:
{"errors":[{"code":324,"message":"The validation of media ids failed."}]}
From what I have read, the video file can be 15mb total with 5mb chunks. But I found a post saying that an user had a similar issue uploading images (not with tweetinvi) where the limit stated is 3mb, but they got this issue, using smaller images not problem.

So I am thinking perhaps the chunking needs to be 1mb?


Anyone else having similar issues?


I have tried to look through the code where you are setting the 5mb chunk limit, but not been able to find it (haven't looked too hard to be honest ;-) but thought would check in here to see if I am the only one.


Am using 0.981 version
Jul 18, 2015 at 8:48 PM
Ignore, my mistake, my video split routine was wrong, so videos over 30 secds
Coordinator
Jul 19, 2015 at 3:41 PM
Hi,

Please note that the VideoPublisher is available in Tweetinvi 0.9.8.2. Also note that this code has been moved into Upload in Tweetinvi 0.9.9.x which is not yet available.

Linvi