質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1574閲覧

PHAsset からURLの取得

knitbow

総合スコア11

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/08/31 21:34

編集2017/09/04 20:18

swift

1 2 func getURL(ofPhotoWith mPhasset: PHAsset, completionHandler : @escaping ((_ responseURL : URL?) -> Void)) { 3 4 if mPhasset.mediaType == .video { 5print(mPhasset) 6 let options: PHVideoRequestOptions = PHVideoRequestOptions() 7 options.deliveryMode = .highQualityFormat 8 options.version = .original 9 PHImageManager.default().requestAVAsset(forVideo: mPhasset, options: options, resultHandler: { (asset, audioMix, info) in 10 11 if let tokenStr = info?["PHImageFileSandboxExtensionTokenKey"] as? String { 12 13 let tokenKeys = tokenStr.components(separatedBy: ";") 14 let urlStr = tokenKeys.filter { $0.contains("/private/var/mobile/Media") }.first 15 16 if let urlStr = urlStr { 17 if let url = URL(string: urlStr) { 18 completionHandler(url) 19 } 20 } 21 } 22 23 24 if let urlAsset = asset as? AVURLAsset { 25 let localVideoUrl = urlAsset.url 26 completionHandler(localVideoUrl) 27 } else { 28 completionHandler(nil) 29 } 30 }) 31 } 32 33 } 34

###前提・実現したいこと
URLを取得したい

###発生している問題・エラーメッセージ
・デバッグしたところ

if let tokenStr = info?["PHImageFileSandboxExtensionTokenKey"] as? String {

まで行かない。

options.deliveryMode = .highQualityFormat options.version = .original

options.deliveryModeは全て試した。
ここまでは、行く。

<PHAsset: 0x10206d310> 44BA136D-E1E0-459B-8AEA-ACED90E93932/L0/001 mediaType=2/0, sourceType=1, (3840x2160), creationDate=2017-08-27 02:54:49 +0000, location=1, hidden=0, favorite=0

色々調べたのですが、力及ばず、、、

すみませんが、宜しくおねがいします。

#呼び出し元の追記

ViewController

1 func qb_imagePickerController(_ imagePickerController: QBImagePickerController!, didFinishPickingAssets assets: [Any]!) { 2 3 for asset in assets { 4 self.getURL(ofPhotoWith: asset as! PHAsset) 5 } 6 7}

QBImagePickerControllerを使用している。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/09/01 00:50 編集

if mPhasset.mediaType == .video { の中には入っているのでしょうか?【追記】その前に、getURL()は呼ばれているのでしょうか?
knitbow

2017/09/01 03:50

修正しました。よろしくお願いします。
fuzzball

2017/09/01 03:57 編集

deliveryModeを変えても同じでしょうか?あと、print(mPhasset)の出力を教えて下さい。
knitbow

2017/09/01 12:42

返事遅くなりすみません。更新しました。
fuzzball

2017/09/04 00:59

「if let tokenStr = ...」まで行かないということは、PHImageManager.default().requestAVAsset()のハンドラの中に入らないということですよね?iPhoneで録った動画しか試していませんが、こちらでは問題なく動作しました。
knitbow

2017/09/04 01:27

おっしゃるとおり、PHImageManager.default().requestAVAssetのハンドラに入らないです。私も、iphoneて試してます。
YokemuraTakeshi

2017/09/04 03:43

iCloudアイテムである可能性はありますか?
knitbow

2017/09/04 20:12

icloudアイテムではないです。。。
fuzzball

2017/09/05 00:45

「私も、iphoneて試してます」というのはiPhoneで録ったという意味でしょうか?違うのであればiPhoneで録った動画で試してみて下さい。あと、動画じゃなくて画像でも(コードを修正して)試してみて下さい。
knitbow

2017/09/05 12:01

iphoneで撮ったビデオです。画像のurlは取得出来ました。
guest

回答1

0

ベストアンサー

回答ではないのですが、こちらで確認した全(というほどでもない)コードを載せておきます。
確認した端末は 5s です。

swift

1import UIKit 2import Photos 3 4class ViewController: UIViewController { 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 9 let assets = PHAsset.fetchAssets(with: .video, options: nil) 10 assets.enumerateObjects { (asset, index, _) in 11 print("#\(index) \(asset.pixelWidth) x \(asset.pixelHeight)") 12 self.getURL(ofPhotoWith: asset) 13 } 14 } 15 16 func getURL(ofPhotoWith mPhasset: PHAsset) { 17 18 if mPhasset.mediaType == .video { 19 let options: PHVideoRequestOptions = PHVideoRequestOptions() 20 options.deliveryMode = .highQualityFormat 21 options.version = .original 22 PHImageManager.default().requestAVAsset(forVideo: mPhasset, options: options, resultHandler: { (asset, audioMix, info) in 23 print(info) 24 }) 25 } 26 } 27}

投稿2017/09/04 02:27

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

knitbow

2017/09/04 20:11

動作確認ありがとうございます。 上記のコードで試しました。 print("#\(index) \(asset.pixelWidth) x \(asset.pixelHeight)")は出力されるのですが、 print(info)は、やっぱり通らないです。 私は、iphone7plusです。機種に関係あるのでしょうか・・・
fuzzball

2017/09/06 00:44

iPhone 7 Plusで試しましたが正常に取得できました。4K(3840x2160)でも大丈夫でした。こうなるとお手上げですね‥。
knitbow

2017/10/09 21:33

func getURL(ofPhotoWith mPhasset: PHAsset) -> URL{ let options: PHVideoRequestOptions = PHVideoRequestOptions() options.deliveryMode = .highQualityFormat options.version = .original var urlStr2 = URL(string:"") let semaphore = DispatchSemaphore(value: 0) PHImageManager.default().requestAVAsset(forVideo: mPhasset, options: options, resultHandler: { (asset, audioMix, info) in if let tokenStr = info?["PHImageFileSandboxExtensionTokenKey"] as? String { let tokenKeys = tokenStr.components(separatedBy: ";") let urlStr = tokenKeys.filter { $0.contains("/private/var/mobile/Media") }.first urlStr2 = URL(string:urlStr!) if let urlStr = urlStr { if let url = URL(string: urlStr) { print(url.lastPathComponent) print(url.pathExtension) } } } defer {semaphore.signal() } }) semaphore.wait(timeout: DispatchTime.distantFuture) return urlStr2! } 同期処理を入れたら、できました。 長い間、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問