ios - twittear - compartir videos de youtube en twitter
Comparte videos en Twitter a través de la aplicación de iOS (6)
¡Pude subir videos a Twitter con éxito! A continuación se detallan los pasos de los documentos de twitter:
Solicitud de cuenta de twitter
accountStore.requestAccessToAccounts(with: twitterAccountType,options:nil){(granted, error) in
POST media / carga (INIT)
params["command"] = "INIT" params["total_bytes"] = String(videoData.length) params["media_type"] = "video/mov"
POST media / carga (APPEND)
params["command"] = "APPEND" params["media_id"] = mediaId params["segment_index"] = String(chunk)
POST media / carga (FINALIZAR)
params["command"] = "FINALIZE" params["media_id"] = mediaId
POST media / carga
params["status"] = twitterDescription params["media_ids"] = mediaId
Aquí está twitter doc link https://dev.twitter.com/rest/media/uploading-media.html
Por favor, multa la solución detallada para subir videos a Twitter usando SLRequest aquí.
http://swiftoverflow.blogspot.in/2017/04/upload-video-to-twitter-using-slrequest.html
¿Es posible compartir un video usando SLRequest?
Puedo compartir imágenes usando el mismo
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 !");
}
}];
He estado leyendo la documentación de la API de subida de videos de Twitter y es realmente bastante simple. Básicamente, necesitas hacer 3 solicitudes de POST a su API. El video que estás cargando también está limitado a 15 MB de tamaño.
Las cargas que usan este punto final requieren al menos 3 llamadas, una para inicializar la solicitud, que devuelve el id_medio, una o más llamadas para agregar / cargar datos codificados en binario o base64, y una última llamada para finalizar la carga y hacer que media_id pueda usarse con otra recursos.
Entonces funciona así:
Solicitud 1: envíe una solicitud de inicio con el tamaño de video en bytes. Esto devolverá un número de identificación de medios que debemos usar en la solicitud 2 y 3.
Solicitud 2: use el número de ID de medio devuelto de la solicitud 1 para cargar los datos de video.
Solicitud 3: una vez que la carga del video haya finalizado, envíe una solicitud de "FINALIZAR" a la API de Twitter. Esto le permite a la API de Twitter saber que todos los fragmentos del archivo de video han terminado de cargarse.
Nota: La API de Twitter acepta cargas de video en "fragmentos". Entonces, si su archivo de video es bastante grande, puede dividirlo en más de un archivo y, por lo tanto, tendrá que repetir "Solicitud 2" más de una vez (sin olvidar aumentar el número de "segment_index" cada vez).
He intentado codificar esto a continuación. Pruébalo y experimenta con él. Actualizaré mi respuesta más adelante para mejorarla también.
-(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);
}
}];
}
Actualización - Errores de la API de Twitter - https://dev.twitter.com/overview/api/response-codes
En respuesta a su primer comentario, el error 503 significa que los servidores de Twitter están sobrecargados y no pueden manejar su solicitud en este momento.
503 Servicio no disponible Los servidores de Twitter están arriba, pero sobrecargados con solicitudes. Inténtalo más tarde.
Sé cómo subir videos a Twitter use la nueva API. Y lo he intentado, funciona.
Por favor revisa esto: https://github.com/liu044100/SocialVideoHelper
Solo necesitas llamar a este método de clase.
+(void)uploadTwitterVideo:(NSData*)videoData account:(ACAccount*)account withCompletion:(dispatch_block_t)completion;
Espero que pueda resolver tu problema.
Atentamente.
Pruebe esto basado en @Dan answer. No ha sido probado, pero creo que puede funcionar.
Utilice Cocoa-pods : pod ''TwitterKit''
si no usas Pods prueba con tela
//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();});
}
}
}];
}
Esta API funciona de la siguiente manera.
- Iniciar sesión cuando la aplicación (twitter) está instalada y cuando no está instalada
- Credencial de toma de la primera prioridad desde la configuración
Mira este caso
Rápido
Es muy sencillo. Primero debe iniciar sesión en su cuenta de Twitter. Vaya a Configuración del teléfono y haga clic en la aplicación de Twitter e videoUpload
sesión. Ahora solo llame a este videoUpload
función en cualquier lugar.
Video o Chunked uploads Método de referencia
Reemplace su tipo de video / extensión en ese código Y lea atentamente todos los requisitos de 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)
}
}
})
}
He estado buscando compartir soluciones de video en Twitter con las siguientes funciones:
- Soporte de carga de fragmento
- Soporte integrado para la recuperación de credenciales del usuario
Como no pude encontrar uno que satisfaga mi necesidad, decidí escribir uno.
https://github.com/mtrung/TwitterVideoUpload
He estado probando por un tiempo y funciona bien para mí.
Espero eso ayude,
Saludos.