Esempio n. 1
0
        public static async Task <IApiResult <TwitterUploadedMedia> > UploadLargeMediaAsync(
            [NotNull] this IApiAccessor accessor, [NotNull] byte[] media, [NotNull] string mimeType,
            [CanBeNull] long[] additionalOwners, int?chunkSize, [CanBeNull] IProgress <int> sentBytesCallback,
            CancellationToken cancellationToken)
        {
            if (accessor == null)
            {
                throw new ArgumentNullException(nameof(accessor));
            }
            if (media == null)
            {
                throw new ArgumentNullException(nameof(media));
            }
            if (mimeType == null)
            {
                throw new ArgumentNullException(nameof(mimeType));
            }

            var mediaType = MediaFileUtility.GetMediaType(media);

            // maximum video size is 15MB (maximum image is 5MB)
            if (media.Length > 15 * 1024 * 1024)
            {
                throw new ArgumentOutOfRangeException(nameof(media), "media file must be smaller than 5MB.");
            }

            // check the bit array could be chunked
            var csize = chunkSize ?? 5 * 1024 * 1024;

            if (!mediaType.IsMovie() && media.Length <= csize)
            {
                // this item is not needed to split it into pieces
                return(await accessor.UploadMediaAsync(media, additionalOwners, cancellationToken)
                       .ConfigureAwait(false));
            }
            if (csize < 1 || media.Length / csize > 999)
            {
                throw new ArgumentOutOfRangeException(nameof(chunkSize), "chunk size is not appropriate.");
            }

            // chunking media
            var chunks = media.Select((b, i) => new { Data = b, Index = i / csize })
                         .GroupBy(b => b.Index)
                         .Select(g => g.Select(b => b.Data).ToArray())
                         .ToArray();

            // send INIT request
            var initialContent = new MultipartFormDataContent
            {
                { new StringContent("INIT"), "command" },
                { new StringContent(media.Length.ToString()), "total_bytes" },
                { new StringContent(mimeType), "media_type" }
            };

            if (additionalOwners != null)
            {
                initialContent.Add(new StringContent(additionalOwners.Select(id => id.ToString()).JoinString(",")),
                                   "additional_owners");
            }
            var initialResult =
                await accessor.UploadMediaCoreAsync(initialContent, cancellationToken).ConfigureAwait(false);

            // read initial result and prepare sending content
            var mediaId  = initialResult.Result.MediaId;
            var fileName = System.IO.Path.GetRandomFileName();

            var index    = 0;
            var sentSize = 0;

            // send APPEND request for uploading contents
            foreach (var part in chunks)
            {
                var content = new MultipartFormDataContent
                {
                    { new StringContent("APPEND"), "command" },
                    { new StringContent(mediaId.ToString()), "media_id" },
                    { new ByteArrayContent(part), "media", fileName },
                    { new StringContent(index.ToString()), "segment_index" }
                };
                await UploadCoreAsync(accessor, content, cancellationToken).ConfigureAwait(false);

                sentSize += part.Length;
                sentBytesCallback?.Report(sentSize);
                index++;
            }

            // send FINALIZE
            var finalContent = new MultipartFormDataContent
            {
                { new StringContent("FINALIZE"), "command" },
                { new StringContent(mediaId.ToString()), "media_id" }
            };

            return(await UploadMediaCoreAsync(accessor, finalContent, cancellationToken).ConfigureAwait(false));
        }
Esempio n. 2
0
 public static Task <IApiResult <TwitterUploadedMedia> > UploadMediaAsync(
     [NotNull] this IApiAccessor accessor, [NotNull] byte[] image,
     CancellationToken cancellationToken)
 {
     return(accessor.UploadMediaAsync(image, null, cancellationToken));
 }