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

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

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

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

Q&A

解決済

mp4ファイルが保存できない

faipaspijfasjf
faipaspijfasjf

総合スコア260

Swift

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

1回答

0グッド

0クリップ

532閲覧

投稿2022/10/09 08:16

編集2022/10/10 05:27

前提

mp4ファイルをアルバムに保存しようとすると失敗します

実現したいこと

https://hogehoge.com/movie/21838381818.mp4 から動画をダウンロードしてiPhoneのアルバムに保存したいです

アルバムへの保存の流れも知りたいです

発生している問題・エラーメッセージ

Optional(Error Domain=PHPhotosErrorDomain Code=3302 "(null)") Optional("The operation couldn’t be completed. (PHPhotosErrorDomain error 3302.)")

該当のソースコード

swift

1 import Photos 2 3class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { 4 5// 保存 6 @IBAction func saveMovie(_ sender: Any) { 7 8 let url = URL(string: self.url!) 9 10 let request = URLRequest(url: url!) 11 12 let task = URLSession.shared.dataTask(with: request) { (data, response, error) in 13 14 if(data == nil){ 15 print("ダウンロード失敗") 16 return 17 } 18 19 if data!.count == 0 { 20 print("中身がない") 21 22 } else { 23 print("ダウンロード開始") 24 25 //ドキュメントフォルダのパス 26 let path = NSSearchPathForDirectoriesInDomains( 27 .documentDirectory, 28 .userDomainMask, true).last! 29 30 //ファイルのパス 31 let documentDirectoryURL = path 32 33 do { 34 //アプリ内に保存 35 try data?.write(to: URL(fileURLWithPath: documentDirectoryURL)) 36 print("documentDirectoryURLは") 37 print(documentDirectoryURL) 38 39 PHPhotoLibrary.shared().performChanges( 40 { 41 PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(string: documentDirectoryURL)!) 42 }, 43 completionHandler: { (success, err) in 44 if success == true { 45 print("保存成功!") 46 } else { 47 print("保存失敗! \(err) \(err?.localizedDescription)") 48 } 49 }) 50 } catch { 51 print(error.localizedDescription) 52 } 53 } 54 } 55 task.resume() 56 } 57} 58
// 出力結果 ダウンロード開始 documentDirectoryURLは /Users/apple/Library/Developer/CoreSimulator/Devices/AE..../data/Containers/Data/Application/98.../Documents

試したこと①

info.plstは設定済みです
イメージ説明

試したこと②

do { try ...} catch {error.localizedDescription} 追記

// 出力結果② The file “Documents” couldn’t be saved in the folder "22-....-.....”.

補足情報(FW/ツールのバージョンなど)

Xcode 13.4

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

退会済みユーザー

退会済みユーザー

2022/10/09 10:01

https://stackoverflow.com/questions/61044285/save-video-in-photo-library-swift リンク先などを見ると流れはOKっぽいのでしょうかね。 気になったのは次のコードです。 `try? data?.write(to: URL(fileURLWithPath: documentDirectoryURL))` tryの部分でエラーをオプショナルな値に変換するのではなく、 エラーの場合はどのようなエラーが発生しているのか把握するために do-catchステートメントで処理してみたらいかがでしょうか。
faipaspijfasjf

2022/10/10 05:25

コメントありがとうございます。 do { try...} catch { print(error.localizedDescription)} でやると `The file “Documents” couldn’t be saved in the folder “22...-....”.` と出るのでファイル名の重複が原因かもしれません

回答1

1

ベストアンサー

コメントありがとうございます。

リンク先のコードも読んでみると良いと思います。

let dataPath = documentsDirectory.stringByAppendingPathComponent("/videoFileName.mp4")
https://stackoverflow.com/questions/61044285/save-video-in-photo-library-swift

Documentsはディレクトリですので、
stringByAppendingPathComponentでファイルを指定する形になっているみたいです。

追記です。

コメントありがとうございます。
サンプルコードも含めて追記します。

他の青アプリで当該URL(...mp4)をダウンロードしたり保存することは可能です。

こちらはmp4ファイル自体は問題なさそうなのですね。
関係しているかわからないので念の為の確認ですが、ファイルサイズはどれくらいでしょうか?

ちょっとわからなくなってきました、、

一度に全ての問題を対処しようとすると混乱してしまいますので、
1つずつゆっくり確認すると良いと思います。

処理の流れは次のような感じになりますので、
上から順番に、それぞれのポイントで正しく処理ができているか
確認してみると良いと思います。

  1. mp4ファイルダウンロード
  2. ドキュメントディレクトリに保存する([Product]-[Run]するたびにアプリのディレクトリが変わる?ため注意)
  3. 写真アプリに保存する

ちょっと細かい実装は違いますが、
手元の環境(Xcode 14.0)で再現確認したコードも記載しておきます。

swift

1 func action() { 2 Task { 3 // ダウンロード 4 let url = URL(string: "http://localhost:1313/test.mp4")! 5 let (data, response) = try await URLSession.shared.data(from: url) 6 guard let httpResponse = response as? HTTPURLResponse, 7 httpResponse.statusCode == 200 else { 8 print("response: \(response)") 9 return 10 } 11 // ドキュメントディレクトリに保存する 12 let urlDocumentDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 13 let urlFilePath = urlDocumentDirectory.appendingPathComponent("download.mp4") 14 print(urlFilePath) 15 try! data.write(to: urlFilePath) 16 // 写真アプリに保存する 17 PHPhotoLibrary.shared().performChanges { 18 PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: urlFilePath) 19 } completionHandler: { success, error in 20 if let error = error { 21 print("error: \(error)") 22 return 23 } 24 print("success: \(success)") 25 } 26 } 27 }

投稿2022/10/10 05:31

編集2022/10/12 05:06
退会済みユーザー

退会済みユーザー

総合スコア0

faipaspijfasjf😄を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

faipaspijfasjf

2022/10/10 06:20

リンク先の `solution` のコードをアレンジしてみましたが ・アプリ内への保存→成功 ・iPhoneのアルバムへの保存→失敗 でした。
退会済みユーザー

退会済みユーザー

2022/10/10 06:54

コメントありがとうございます。 > ・iPhoneのアルバムへの保存→失敗 エラーは何か出力されていますでしょうか? 最初にアクセスする際に許可設定をしますが、写真への許可はされた状態になっていますでしょうか? 設定ープライバシーとセキュリティー写真ーアプリの名前ー「写真の追加のみ or すべての写真」
faipaspijfasjf

2022/10/10 09:43

・エラーは何も出ていないです。 ・許可等は質問内容でも画像を添付しています。 (間違えていたらご指摘ください)
退会済みユーザー

退会済みユーザー

2022/10/10 09:49

コメントありがとうございます。 エラーは出力されていないのですね・・ 「・iPhoneのアルバムへの保存→失敗」というのは、写真アプリに保存されていないということで判断されたのでしょうか? (その場合、何かしらエラーが出力されるような気もしますよね・・) > ・許可等は質問内容でも画像を添付しています。 Info.plistは開発者側で設定する内容だと思います。 それとは別に、アプリの利用者側が設定する内容が次のものになります。 設定ープライバシーとセキュリティー写真ーアプリの名前ー「写真の追加のみ or すべての写真」 開発者側が許可を求めるように設定しておいても、利用者が許可しなければ写真アプリにアクセスすることができない仕組みになっていると思います。
faipaspijfasjf

2022/10/10 13:43

> (その場合、何かしらエラーが出力されるような気もしますよね・・) 少しコード修正して現在は以下のエラーが出ます。 ・Optional(Error Domain=PHPhotosErrorDomain Code=3302 "(null)") Optional("The operation couldn’t be completed. (PHPhotosErrorDomain error 3302.)") or ・Optional("The operation couldn’t be completed. (PHPhotosErrorDomain error -1.)") > 開発者側が許可を求めるように設定しておいても、利用者が許可しなければ写真アプリにアクセスすることができない仕組みになっていると思います。 こちら実機、シュミレーター共に表示されたアラートで許可を選択しております 設定ープライバシーとセキュリティー写真ーアプリの名前ー「写真の追加のみ or すべての写真」で確認しても『写真の追加のみ』がちゃんとtrueになっております その他 ・実機のストレージを確認(十分余裕がありました) ・ファイルパスに余分な文字列がないか確認しましたがありませんでした 投稿した内容の実装を探してみても意外と見当たらなくて非常に困っています..
退会済みユーザー

退会済みユーザー

2022/10/10 14:07

> 少しコード修正して現在は以下のエラーが出ます。 また少し後退してしまったようですね。 おそらくドキュメントディレクトリにファイルが正しく保存できていないように見えます。 > 『写真の追加のみ』がちゃんとtrueになっております こちらは大丈夫そうですね。 > 投稿した内容の実装を探してみても意外と見当たらなくて非常に困っています.. https://stackoverflow.com/questions/61044285/save-video-in-photo-library-swift このリンク先のコードを少し修正して手元の環境(Xcode 14.0)で再現確認してみたところ、ちゃんと写真アプリに取り込めたのですけどね・・ > ・エラーは何も出ていないです。 3つ前のコメントのこの状況につきまして、そもそも対象のmp4ファイルは、開発中のアプリを通さずに(AirDropなどで)写真アプリに取り込むことが可能なものでしょうか?
faipaspijfasjf

2022/10/12 04:35

返信遅くなりました。 > おそらくドキュメントディレクトリにファイルが正しく保存できていないように見えます。 https://qiita.com/t_punch/items/edab6f323e823be4f527 の内容で確認するとドキュメントにはファイルが1つも存在しなかったです > 開発中のアプリを通さずに(AirDropなどで)写真アプリに取り込むことが可能なものでしょうか? はい。 他の青アプリで当該URL(...mp4)をダウンロードしたり保存することは可能です。 ちょっとわからなくなってきました、、
faipaspijfasjf

2022/10/14 05:32

ありがとうございます。 ただまだ一部の動画が `error: Error Domain=PHPhotosErrorDomain Code=3302 "(null)"` を吐きます。 もう少し調べてわからなくなったら再度質問投稿いたします。 回答していただきありがとうございます。
faipaspijfasjf

2022/10/17 14:08

(保存できないファイルも保存できるようになりました。稀にmp4ファイルが含まれないURLが混在するケースがある事が判明しました。API側の問題でした。それらを解消する処理を追加することで無事全てダウンロードできるようになりしました。回答していただお陰で処理が進みました。ありがとうございます。)

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Swift

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