通过iOS App在Twitter上分享视频

时间:2015-06-03 06:26:59

标签: ios objective-c video twitter social-framework

是否可以使用SLRequest分享视频?

我可以使用相同的

分享图像
SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL parameters:message];

if (isImage)
{
    NSData *data = UIImagePNGRepresentation(imgSelected);
    [postRequest addMultipartData:data withName:@"media" type:@"image/png" filename:@"TestImage.png"];
}

postRequest.account = account;

[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
    if (!error)
    {
        NSLog(@"Upload Sucess !");
    }
}];

6 个答案:

答案 0 :(得分:4)

我一直在阅读Twitter视频上传API文档,它非常简单。您基本上需要向其API发出3个POST请求。您上传的视频也限制为15 MB。

  

使用此端点上传需要至少3次呼叫,一次到   初始化请求,返回media_id,一个或多个调用   附加/上传二进制或base64编码数据,以及最后一次调用   完成上传并使media_id与其他资源一起使用。

所以它的工作原理如下:

  • 请求1:发送包含视频大小的初始化请求(以字节为单位)。这将返回我们必须在请求2和3中使用的媒体ID号。

  • 请求2:使用请求1中返回的媒体ID号上传视频数据。

  • 请求3:视频上传完成后,将“FINALIZE”请求发回Twitter API。这让Twitter API知道视频文件的所有块都已完成上传。

注意 Twitter API接受“chunk”中的视频上传。因此,如果您的视频文件很大,您可能需要将其拆分为多个文件,因此您必须多次重复“请求2”(不要忘记每次都增加“segment_index”数字)。< / p>

我已经开始编写以下代码了。尝试一下并尝试一下。我稍后会更新我的答案以改进它。

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 

    // Assign the mediatype to a string 
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];

    // Check the media type string so we can determine if its a video
    if ([mediaType isEqualToString:@"public.movie"]) {

        NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
        NSData *webData = [NSData dataWithContentsOfURL:videoURL];

        // Get the size of the file in bytes.
        NSString *yourPath = [NSString stringWithFormat:@"%", videoURL];
        NSFileManager *man = [NSFileManager defaultManager];
        NSDictionary *attrs = [man attributesOfItemAtPath:yourPath error: NULL];
        UInt32 result = [attrs fileSize];

        //[self tweetVideoStage1:webData :result];
        [self tweetVideo:webData :result :1 :@"n/a"];
    }
}

-(void)tweetVideo:(NSData *)videoData :(int)videoSize :(int)mode :(NSString *)mediaID {

    NSURL *twitterVideo = [NSURL URLWithString:@"https://upload.twitter.com/1.1/media/upload.json"];

    // Set the parameters for the first twitter video request.
     NSDictionary *postDict;

    if (mode == 1) {

        postDict = @{@"command": @"INIT",
                     @"total_bytes" : videoSize,
                     @"media_type" : @"video/mp4"};
    }

    else if (mode == 2) {

        postDict = @{@"command": @"APPEND",
                     @"media_id" : mediaID,
                     @"segment_index" : @"0",
                     @"media" : videoData };
    }

    else if (mode == 3) {

        postDict = @{@"command": @"FINALIZE",
                     @"media_id" : mediaID };
    }

    SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL:twitterVideo parameters:postDict];

    // Set the account and begin the request.
    postRequest.account = account;
    [postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {

        if (!error) {

            if (mode == 1) {

                // Parse the returned data for the JSON string
                // which contains the media upload ID.
                NSMutableDictionary *returnedData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error]
                NSString *tweetID = [NSString stringWithFormat:@"%@", [returnedData valueForKey:@"media_id_string"]];
                [self tweetVideo:videoData :result :2 :tweetID];
            }

            else if (mode == 2) {
                [self tweetVideo:videoData :result :3 :mediaID];
            }
        }

        else {
            NSLog(@"Error stage %d - %", mode, error);
        }
    }];
}

更新 - Twitter API错误 - https://dev.twitter.com/overview/api/response-codes

在回答您的第一条评论时,错误503表示Twitter服务器已超载且无法立即处理您的请求。

  

503服务不可用Twitter服务器已启动但已超载   有请求。稍后再试。

答案 1 :(得分:4)

我知道如何使用新API将视频上传到Twitter。我尝试过它,它有效。

请检查:https://github.com/liu044100/SocialVideoHelper

你只需要调用这个类方法。

+(void)uploadTwitterVideo:(NSData*)videoData account:(ACAccount*)account withCompletion:(dispatch_block_t)completion;

希望它可以解决您的问题。

最诚挚的问候。

答案 2 :(得分:2)

一直在寻找在Twitter解决方案上分享以下功能的视频:

  • 支持块上传
  • 内置支持用户的凭据检索

由于我无法找到一个符合要求的会议,所以我决定写一个。

https://github.com/mtrung/TwitterVideoUpload

我现在已经测试了一段时间,对我来说效果很好。

希望它有所帮助,

问候。

答案 3 :(得分:1)

在@Dan回答中尝试这个。它没有经过测试,但我认为它可以工作。

使用Cocoa-pods pod'TwitterKit'

如果您不使用Pod,请尝试使用fabric

//for Extern call
//Mode is 1
//MediaId is 0
- (void)uploadTwitterVideo:(NSData*)videoData videoTitle:(NSString *)title desc:(NSString *)desc withMode:(int)mode  mediaID:(NSString *)mediaID withCompletion:(dispatch_block_t)completion
{
    NSString *twitterPostURL = @"https://upload.twitter.com/1.1/media/upload.json";

    NSDictionary *postParams;
    if (mode == 1) {
        postParams = @{@"command": @"INIT",
                       @"total_bytes" : [NSNumber numberWithInteger: videoData.length].stringValue,
                       @"media_type" : @"video/mp4"};
    } else if (mode == 2) {
        postParams = @{@"command": @"APPEND",
                       @"media_id" : mediaID,
                       @"segment_index" : @"0"};
    } else if (mode == 3) {
        postParams = @{@"command": @"FINALIZE",
                       @"media_id" : mediaID };
    } else if (mode == 4) {
        postParams = @{@"status": desc,
                       @"media_ids" : @[mediaID]};
    }

    TWTRAPIClient *twitterInstance = [[Twitter sharedInstance] APIClient];
    NSError *error;
    NSURLRequest *requestTw = [twitterInstance URLRequestWithMethod:@"POST" URL:twitterPostURL parameters:postParams error:&error];

    [twitterInstance sendTwitterRequest:requestTw completion:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        NSLog(@"HTTP Response: %li, responseData: %@", (long)response, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        if (error) {
            NSLog(@"There was an error:%@", [error localizedDescription]);
        } else {

            if (mode == 1) {
                NSMutableDictionary *returnedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&connectionError];
                NSString *mediaIDResponse = [NSString stringWithFormat:@"%@", [returnedData valueForKey:@"media_id_string"]];
                NSLog(@"stage one success, mediaID -> %@", mediaID);
                [self uploadTwitterVideo:videoData videoTitle:title desc:desc withMode:2 mediaID:mediaIDResponse withCompletion:completion];
            } else if (mode == 2) {
                [self uploadTwitterVideo:videoData videoTitle:title desc:desc withMode:3 mediaID:mediaID withCompletion:completion];
            } else if (mode == 3) {
                [self uploadTwitterVideo:videoData videoTitle:title desc:desc withMode:4 mediaID:mediaID withCompletion:completion];
            } else if (mode == 4) {
                DispatchMainThread(^(){completion();});
            }
        }
    }];
}

此API的工作原理如下。

- 安装应用程序(twitter)时以及未安装时登录

- 首先从设置

获取凭据

选中此case

答案 4 :(得分:0)

<强>夫特

非常简单。 首先,您需要登录您的Twitter帐户。转到电话设置,然后单击Twitter应用程序并登录。 现在只需将videoUpload func调用到任何地方

视频或分块上传方法 Reference

  

替换该代码上的视频类型/扩展名       并仔细阅读所有twitter requirements

var twitterAccount = ACAccount()

        func videoUpload{
                let path = Bundle.main.path(forResource: "file-Name", ofType:"mp4")

                let filePath = path
                var fileSize = UInt64()

                do {
                    //return [FileAttributeKey : Any]
                    let attr = try FileManager.default.attributesOfItem(atPath: filePath!)
                    fileSize = attr[FileAttributeKey.size] as! UInt64

                    //if you convert to NSDictionary, you can get file size old way as well.
                    let dict = attr as NSDictionary
                    fileSize = dict.fileSize()
                } catch {
                    print("Error: \(error)")
                }

                let accountStore = ACAccountStore()
                let twitterAccountType = accountStore.accountType(withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)
                accountStore.requestAccessToAccounts(with: twitterAccountType, options: nil) { (granted, error) in

                    if granted {
                        let accounts = accountStore.accounts(with: twitterAccountType)
                        if (accounts?.count)! > 0 {
                            self.twitterAccount = accounts?.last as! ACAccount
                        }}}


                twitterAccount = Twitter.sharedInstance().sessionStore.session() as! ACAccount
        uploadVideoToTwitter(videoURL: URL(string : path!)! as NSURL, fileSize: UInt32(fileSize))
        }

    func uploadVideoToTwitter(videoURL:NSURL,fileSize: UInt32) {

            if let videoData = NSData(contentsOfFile: videoURL.path!){
                self.tweetVideoInit(videoData: videoData, videoSize: Int(fileSize))
            }
        }

        func tweetVideoInit(videoData:NSData,videoSize:Int) {

            let uploadURL = NSURL(string:"https://upload.twitter.com/1.1/media/upload.json")

            var params = [String:String]()

            params["command"] = "INIT"
            params["total_bytes"]  = String(videoData.length)
            params["media_type"]  = "video/mp4"

            let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter,
                                        requestMethod: SLRequestMethod.POST,
                                        url: uploadURL as URL!,
                                        parameters: params)

            postRequest?.account = self.twitterAccount;

            postRequest?.perform(handler: { ( responseData, urlREsponse,error) in
                if let err = error {
                    print(error as Any)
                }else{
                    do {
                        let object = try JSONSerialization.jsonObject(with: responseData! as Data, options: .allowFragments)
                        if let dictionary = object as? [String: AnyObject] {

                            if let tweetID = dictionary["media_id_string"] as? String{
                                self.tweetVideoApped(videoData: videoData, videoSize: videoSize, mediaId: tweetID, chunk: 0)
                            }
                        }
                    }
                    catch {
                        print(error)
                    }
                }
            })
        }

        func tweetVideoApped(videoData:NSData,videoSize:Int ,mediaId:String,chunk:NSInteger) {

            let uploadURL = NSURL(string:"https://upload.twitter.com/1.1/media/upload.json")

            var params = [String:String]()

            params["command"] = "APPEND"
            params["media_id"]  = mediaId
            params["segment_index"]  = String(chunk)

            let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter,
                                        requestMethod: SLRequestMethod.POST,
                                        url: uploadURL as URL!,
                                        parameters: params)

            postRequest?.account = self.twitterAccount
            postRequest?.addMultipartData(videoData as Data!, withName: "media", type: "video/mov", filename:"mediaFile")

            postRequest?.perform(handler: { ( responseData, urlREsponse,error) in
                if let err = error {
                    print(err)

                }else{
                    self.tweetVideoFinalize(mediaId: mediaId)
                }
            })
        }

        func tweetVideoFinalize(mediaId:String) {
            let uploadURL = NSURL(string:"https://upload.twitter.com/1.1/media/upload.json")

            var params = [String:String]()
            params["command"] = "FINALIZE"
            params["media_id"]  = mediaId

            let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter,
                                        requestMethod: SLRequestMethod.POST,
                                        url: uploadURL as URL!,
                                        parameters: params)

            postRequest?.account = self.twitterAccount;
            postRequest?.perform(handler: { ( responseData, urlREsponse,error) in
                if let err = error {
                    print(err)
                }else{
                    do {
                        let object = try JSONSerialization.jsonObject(with: responseData! as Data, options: .allowFragments)
                        if let dictionary = object as? [String: AnyObject] {
                            self.postStatus(mediaId: mediaId)
                        }
                    }
                    catch {
                        print(error)
                    }
                }
            })
        }

        func postStatus(mediaId:String) {

            let uploadURL = NSURL(string:"https://api.twitter.com/1.1/statuses/update.json")

            var params = [String:String]()
            params["status"] = "my first Video Upload"
            params["media_ids"]  = mediaId

            let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter,
                                        requestMethod: SLRequestMethod.POST,
                                        url: uploadURL as URL!,
                                        parameters: params)

            postRequest?.account = self.twitterAccount;

            postRequest?.perform(handler: { ( responseData, urlREsponse,error) in
                if let err = error {
                    print(err)
                }else{
                    do {
                        let object = try JSONSerialization.jsonObject(with: responseData! as Data, options: .allowFragments)
                        if let dictionary = object as? [String: AnyObject] {
                            print("video uploaded")
                        }
                    }
                    catch {
                        print(error)
                    }
                }
            })
        }

答案 5 :(得分:-1)

我能够成功将视频上传到Twitter! 以下是Twitter文档中提到的步骤:

  1. 申请推特账号

    accountStore.requestAccessToAccounts(with: twitterAccountType,options:nil){(granted, error) in
    
  2. POST媒体/上传(INIT)

    params["command"] = "INIT"
    params["total_bytes"]  = String(videoData.length)
    params["media_type"]  = "video/mov"
    
  3. POST媒体/上传(APPEND)

    params["command"] = "APPEND"
    params["media_id"]  = mediaId
    params["segment_index"]  = String(chunk)
    
  4. POST媒体/上传(FINALIZE)

    params["command"] = "FINALIZE"
    params["media_id"]  = mediaId
    
  5. POST媒体/上传

    params["status"] = twitterDescription
    params["media_ids"]  = mediaId
    
  6. 这是Twitter文档链接https://dev.twitter.com/rest/media/uploading-media.html

    请使用SLRequest在此处详细解决上传到Twitter的视频。

    http://swiftoverflow.blogspot.in/2017/04/upload-video-to-twitter-using-slrequest.html