アプリで動画をInstagramにアップロードできるようにします。
Instagram IPhone Hooks は、iphoneフックを使用して写真をInstagramにアップロードする方法に関する情報を提供します。私の質問は、ビデオを除いて同じことを達成する方法について経験がある人はいますか?
InstagramのAPIは、サードパーティアプリケーションからのアップロードを直接サポートしていません。そのため、ユーザーに機能を提供する際に、ユーザーエクスペリエンスの面倒な妥協を行う必要があります。
まず、Instagramにアップロードするビデオを準備し、そのパスをどこかに保存します
次に、ユーザーのカメラロールに保存します。
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(filePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
}
第三に、ビデオが保存されたので、ビデオをInstagramにアップロードするには、アップロードボタンをクリックした後、カメラロールから選択する必要があることをユーザーに伝えます。
アップロードボタンは次のことを行うだけです。
NSURL *instagramURL = [NSURL URLWithString:@"instagram://camera"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
}
Instagram APIが、アップロードの目的でAPIエンドポイントを介したメディアの即時選択をサポートしていないことは非常にばかげていますが、現在のところ、これが唯一の方法です。
同様の質問がありました: Instagram Video iPhone Hook そして私はそれを見つけました。文書化されていないiPhoneフックがあり、iPhoneの写真ロールからアセットを自動的に選択し、ビデオのキャプションをプリロードできます。これにより、FlipagramsアプリがInstagramとビデオを共有するのと同じユーザーエクスペリエンスが得られます。
instagram:// library?AssetPath = assets-library%3A%2F%2Fasset%2Fasset.mp4%3Fid%3D8864C466-A45C-4C48-B76F-E3C421711E9D%26ext%3Dmp4&InstagramCaption = Some%20Preloaded%20Caption
NSURL *videoFilePath = ...; // Your local path to the video
NSString *caption = @"Some Preloaded Caption";
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:[NSURL URLWithString:videoFilePath] completionBlock:^(NSURL *assetURL, NSError *error) {
NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:@"instagram://library?AssetPath=%@&InstagramCaption=%@",[assetURL absoluteString].percentEscape,caption.percentEscape]];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
}
}];
で試してください:
instagram://library?AssetPath=yourVideoPath
私はここで解決策を見つけました: http://blog.horizon.camera/post/102273431070/video-share-objc-ios-instagram
IOS 9用に更新されました。
まず、iOS9の場合、Info.plist
ファイルに追加する必要があります。キーLSApplicationQueriesSchemes
に値instagram
を追加します。これにより、Instagramスキームがホワイトリストに登録されます。 詳細はこちら
Johnnyg17に基づいて動作するコードは次のとおりです。
NSString *moviePath = @"<# /path/to/movie #>";
NSString *caption = @"<# Your caption #>";
NSURL *movieURL = [NSURL fileURLWithPath:moviePath isDirectory:NO];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:movieURL
completionBlock:^(NSURL *assetURL, NSError *error)
{
NSURL *instagramURL = [NSURL URLWithString:
[NSString stringWithFormat:@"instagram://library?AssetPath=%@&InstagramCaption=%@",
[[assetURL absoluteString] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]],
[caption stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]]]
];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
}
else {
NSLog(@"Can't open Instagram");
}
}];
サンプルのinstagramURLは次のとおりです。
instagram://library?AssetPath=assets%2Dlibrary%3A%2F%2Fasset%2Fasset%2Emov%3Fid%3D69920271%2D2D44%2D4A84%2DA373%2D13602E8910B6%26ext%3Dmov&InstagramCaption=Super%20Selfie%20Dance%20%F0%9F%98%83
2016/5の更新:ALAssetsLibrary
はユーザーのフォトアルバムに保存するために非推奨になり、 Photos Framework が推奨されるようになりました。
Instagramはこれを更新して、新しい写真ライブラリを使用しました。これで、画像/動画のURLを渡す代わりに、対応するPHAssetのlocalIdentifierを渡すことができます。
PHAsset *first = /* Some PHAsset that you want to open Instagram to */;
NSURL *instagramURL = [NSURL URLWithString:[@"instagram://library?AssetPath=" stringByAppendingString:first.localIdentifier]];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
}
Swift Instagramの共有ビデオのコードです。
ここで、videoURLは動画のアセットURLです。
func shareVideoToInstagram()
{
let videoURL : NSURL = "URL of video"
let library = ALAssetsLibrary()
library.writeVideoAtPathToSavedPhotosAlbum(videoURL) { (newURL, error) in
let caption = "write your caption here..."
let instagramString = "instagram://library?AssetPath=\((newURL.absoluteString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet()))!)&InstagramCaption=\((caption.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet()))!)"
let instagramURL = NSURL(string: instagramString)
if UIApplication.sharedApplication().canOpenURL(instagramURL!)
{
UIApplication.sharedApplication().openURL(instagramURL!)
}
else
{
print("Instagram app not installed.")
}
}
}
Info.plistのコードの下に追加したことを確認してください。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
</array>
Instagram APIのアップロード機能は、特にビデオファイルに関しては非常に制限されています。
私の理解では、メディアをInstagramにアップロードする場合、基本的に2つの選択肢があります。 Document Interaction APIを使用して画像をInstagramアプリに渡すか、Instagramカメラを呼び出して、ユーザーにカメラロールから選択するように依頼できます( Nico のように)。
ドキュメントインタラクションシステムを介してInstagramにのみJPEGまたはPNGファイルを渡すことができると確信しているので、ビデオについては今のところカメラロールで動けなくなると思います。これは間違いなく理想的ではありません-現在作業中のアプリはiPhoneフックを使用していますが、InstagramがAPIを改善するまで画像を使用することにしました。
私は以下のコードを使用しましたが、それは私のために働いています。
` [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
switch (status) {
case PHAuthorizationStatusAuthorized: {
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"instagram://"]])
{
[MMProgressHUD setPresentationStyle:MMProgressHUDPresentationStyleExpand];
[MMProgressHUD showWithTitle:APPNAME status:@"Please wait..."];
_FinalVideoPath = [_FinalVideoPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
NSURL *videoUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@", _FinalVideoPath]];
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(q, ^{
NSData *videoData = [NSData dataWithContentsOfURL:videoUrl];
dispatch_async(dispatch_get_main_queue(), ^{
// Write it to cache directory
NSString *videoPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"file.mov"];
[videoData writeToFile:videoPath atomically:YES];
[self createAlbumInPhotosLibrary:APPNAME videoAtFile:[NSURL fileURLWithPath:videoPath]ShareOnString:@"Instagram"];
});
});
}
else
{
[MMProgressHUD dismiss];
[STMethod showAlert:self Title:APPNAME Message:@"Please install Instagram to share this video" ButtonTitle:@"Ok"];
}
break;
}
case PHAuthorizationStatusRestricted: {
[self PhotosDenied];
break;
}
case PHAuthorizationStatusDenied: {
[self PhotosDenied];
break;
}
default:
{
break;
}
}
}];
- (void)createAlbumInPhotosLibrary:(NSString *)photoAlbumName videoAtFile:(NSURL *)videoURL ShareOnString:(NSString*)ShareOnStr
{
// RELIVIT_moments
__block PHFetchResult *photosAsset;
__block PHAssetCollection *collection;
__block PHObjectPlaceholder *placeholder;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"title = %@", photoAlbumName];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
// Create the album
if (!collection)
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *createAlbum = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:photoAlbumName];
placeholder = [createAlbum placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
PHFetchResult *collectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[placeholder.localIdentifier]
options:nil];
collection = collectionFetchResult.firstObject;
[self saveVideoInRelivitFolderSetPlaceHolder:placeholder photosAsset:photosAsset collection:collection VideoAtFile:videoURL ShareOnStr:ShareOnStr];
}
else
{
[MMProgressHUD dismiss];
}
}];
} else {
[self saveVideoInRelivitFolderSetPlaceHolder:placeholder photosAsset:photosAsset collection:collection VideoAtFile:videoURL ShareOnStr:ShareOnStr];
}
}
- (void)saveVideoInRelivitFolderSetPlaceHolder:(PHObjectPlaceholder *)placeholderLocal photosAsset:(PHFetchResult *)photosAssetLocal collection:(PHAssetCollection *)collectionLocal VideoAtFile:(NSURL *)videoURL ShareOnStr:(NSString*)ShareOnstring
{
__block PHFetchResult *photosAsset = photosAssetLocal;
__block PHAssetCollection *collection = collectionLocal;
__block PHObjectPlaceholder *placeholder = placeholderLocal;
// Save to the album
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:videoURL];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection
assets:photosAsset];
[albumChangeRequest addAssets:@[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
NSLog(@"done");
NSString *LocalIdentifire=placeholder.localIdentifier;
NSString *AssetIdentifire=[LocalIdentifire stringByReplacingOccurrencesOfString:@"/.*" withString:@""];
NSString *Extension=@"mov";
NSString *AssetURL=[NSString stringWithFormat:@"assets-library://asset/asset.%@?id=%@&ext=%@",Extension,AssetIdentifire,Extension];
NSURL *aSSurl=[NSURL URLWithString:AssetURL];
[MMProgressHUD dismiss];
if ([ShareOnstring isEqualToString:@"Instagram"])
{
NSLog(@"%@",AssetURL);
NSString *caption = @"#Zoetrope";
NSURL *instagramURL = [NSURL URLWithString:
[NSString stringWithFormat:@"instagram://library?AssetPath=%@&InstagramCaption=%@",
[[aSSurl absoluteString] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]],
[caption stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]]]
];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL])
{
[MMProgressHUD dismiss];
[[UIApplication sharedApplication] openURL:instagramURL];
}
else
{
NSLog(@"Can't open Instagram");
[MMProgressHUD dismiss];
[STMethod showAlert:self Title:APPNAME Message:@"Please install Instagram to share this video" ButtonTitle:@"Ok"];
}
}
else
{
NSString *videoPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"file.mov"];
NSError *removeError = nil;
[[NSFileManager defaultManager] removeItemAtURL:[NSURL fileURLWithPath:videoPath] error:&removeError];
NSLog(@"%@",[removeError localizedDescription]);
ZShareSuccessViewController *ShareView=[self.storyboard instantiateViewControllerWithIdentifier:@"ZShareSuccessViewController"];
[self.navigationController pushViewController:ShareView animated:true];
}
}
else
{
if (![ShareOnstring isEqualToString:@"Instagram"] || [ShareOnstring isEqualToString:@"facebook"])
{
[self PhotosDenied];
}
[MMProgressHUD dismiss];
NSLog(@"%@", error.localizedDescription);
}
}];
}
`