繁体   English   中英

通过iOS App在Twitter上分享视频

[英]Share videos on Twitter via iOS App

是否可以使用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 !");
    }
}];

我一直在阅读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接受“块”中的视频上传。 因此,如果您的视频文件很大,您可能希望将其拆分为多个文件,因此您必须多次重复“请求2”(不要忘记每次都增加“segment_index”数字)。

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

-(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服务器已启动,但请求超载。 稍后再试。

我知道如何使用新API将视频上传到twitter。 我尝试过它,它的工作原理。

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

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

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

希望它能解决你的问题。

最好的祝福。

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

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

由于我找不到一次会议,所以我决定写一篇。

https://github.com/mtrung/TwitterVideoUpload

我现在已经测试了一段时间,它对我很有用。

希望能帮助到你,

问候。

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

使用Cocoa-podspod'TwitterKit'

如果你不使用Pods尝试与面料

//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)时以及未安装时登录

- 首先从设置中获取凭证

检查这种情况

迅速

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

视频或分块上传方法 参考

在该代码上替换您的视频类型/扩展名并仔细阅读所有Twitter 要求

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)
                    }
                }
            })
        }

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

  1. 请求Twitter帐户

     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 

这是推特文档链接https://dev.twitter.com/rest/media/uploading-media.html

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM