ホーム

AVFoundationでアルバムから写真を選択して保存 Swift3

 

環境

  • swift
  • Swift3
  • Xcode
  • Xcode9
  • AVFoundation
  • video

ソース

GitHub

 

実行

on.gif

説明

iOSのアルバムから動画を選択してavfoundationでmacのドキュメントフォルダにアルバムから選択した動画を生成して保存します

実装

//
//  ViewController.swift
//  video-edit
//
//  Created by ryosuke-hujisawa on 2017/10/04.
//  Copyright © 2017年 ryosuke-hujisawa. All rights reserved.
//

import UIKit
import AVFoundation
import AVKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    let imagePickerController = UIImagePickerController()
    var videoURL: URL?

    @IBAction func ChoiceCamera(_ sender: Any) {

        print("UIBarButtonItem。カメラロールから動画を選択")
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.delegate = self
        imagePickerController.mediaTypes = ["public.image", "public.movie"]
        present(imagePickerController, animated: true, completion: nil)
    }





    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        //アルバムから選択した動画を変数に代入
        let documentsPath = info[UIImagePickerControllerMediaURL] as! URL!
        videoURL =  documentsPath

        //viewを戻す
        picker.dismiss(animated: true, completion: nil)
    }






    @IBAction func SaveMovies(_ sender: Any) {

        // 動画のurlを定義する
        // Define the url of the video
        let url = videoURL
        //URL(string: "http://160.16.120.119/kkk.m4v")

        // 動画URLからアセットを生成
        // Generate assets from video URL
        let videoAsset: AVURLAsset = AVURLAsset(url: url!)

        // アセットからトラックを取得
        // Get a track from an asset
        let videoTrack: AVAssetTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0]
        let audioTrack: AVAssetTrack = videoAsset.tracks(withMediaType: AVMediaType.audio)[0]

        // ベースとなる動画のコンポジション作成
        // Composition creation of the base video
        let mainComposition : AVMutableComposition = AVMutableComposition()

        // コンポジションのトラック作成
        // Creating composition tracks
        let compositionVideoTrack: AVMutableCompositionTrack = mainComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)!

        let compositionAudioTrack: AVMutableCompositionTrack = mainComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)!

        // コンポジションの設定
        // Composition setting
        try! compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: videoTrack, at: kCMTimeZero)
        try! compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: audioTrack, at: kCMTimeZero)















        // ロゴのCALayerの作成
        // Create logo CALayer
        //let logoImage : UIImage = UIImage(named: "logo")!
        // UIImage インスタンスの生成
        // 画像はAssetsに入れてないのとjpgなので拡張子を入れます
        let image1:UIImage = UIImage(named:"logo.png")!

        // UIImageView 初期化
        let logoImage = UIImageView(image:image1)




        let logoLayer: CALayer = CALayer()
        logoLayer.contents = logoImage
        logoLayer.frame = CGRect(x: 5, y: 25, width: 57, height: 57)
        logoLayer.opacity = 0.9

        // 動画のサイズを取得
        // Get video size
        let videoSize: CGSize = videoTrack.naturalSize


        // 親レイヤーを作成
        // Create parent layer
        let parentLayer: CALayer = CALayer()
        let videoLayer: CALayer = CALayer()
        parentLayer.frame = CGRect(x: 0, y: 0, width: videoSize.width, height: videoSize.height)
        videoLayer.frame = CGRect(x: 0, y: 0, width: videoSize.width, height: videoSize.height)
        parentLayer.addSublayer(videoLayer)
        parentLayer.addSublayer(logoLayer)

        // 合成用コンポジション作成
        // Composition composition creation
        let videoComp = AVMutableVideoComposition()
        videoComp.renderSize = videoSize
        videoComp.frameDuration = CMTimeMake(1, 30)
        videoComp.animationTool = AVVideoCompositionCoreAnimationTool.init(postProcessingAsVideoLayer: videoLayer, in: parentLayer)

        // インストラクション作成
        // Instruction creation
        let instruction: AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
        instruction.timeRange = CMTimeRangeMake(kCMTimeZero, mainComposition.duration)
        let layerInstruction: AVMutableVideoCompositionLayerInstruction = AVMutableVideoCompositionLayerInstruction.init(assetTrack: videoTrack)
        instruction.layerInstructions = [layerInstruction]

        // インストラクションを合成用コンポジションに設定
        // Set Instruction to Composition for Composition
        videoComp.instructions = [instruction]















        // 動画のコンポジションをベースにAVAssetExportを生成
        // Generate AVAssetExport based on composition of video
        let assetExport = AVAssetExportSession.init(asset: mainComposition, presetName: AVAssetExportPresetMediumQuality)

        /*



         下記が画像を動画に合成する処理。下記を記述する動画が生成されなくなる。
         下記の処理を消すと、正常にmacのドキュメントフォルダに動画が生成される


         Process below to combine images into moving images. A moving image describing the following will not be generated.
         When the following processing is deleted, a movie is normally generated in the mac document folder



         */
        // 合成用コンポジションを設定
        // Set composition for composition
        assetExport!.videoComposition = videoComp

        // 生成された動画を保存する場所のurlとファイルの名前を設定(今回はmacの中のDocumentsディレクトリに保存)
        // Set the url and file name where the generated video will be saved (this time saved in the Documents directory in mac)
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL

        //生成する動画の名前
        // Name of video to generate
        let filePath = documentsDirectory.appendingPathComponent("rendered-audio.m4v")

        // エクスポートファイルのビデオタイプの設定
        // Setting the video type of the export file
        assetExport?.outputFileType = AVFileType.mov

        // 出力されるurlの設定
        // Setting output url
        assetExport?.outputURL = filePath

        // これは必要?
        // Is this necessary?

        //assetExport?.shouldOptimizeForNetworkUse = true

        assetExport?.exportAsynchronously {

            //出力されたファイルのパスをprint表示
            //Print the path of the outputted file

            print("finished: \(filePath) :  \(String(describing: assetExport?.status.rawValue)) ")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        print("Hello World")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
Pocket
LinkedIn にシェア

エンジニアにおすすめできる本

Card image cap
リーダブルコード

より良いコードを書くためのシンプルで実践的なテクニック

Card image cap
Webを支える技術

HTTP,URI,HTML,そしてREST

Card image cap
誰でもPythonで作れる

儲かるAIとソフトウェアの作り方

Card image cap
プログラマが知るべき97のこと

現場で使える実践哲学のマスターピース

Card image cap
情熱プログラマー

時代を超えて。ソフトウェア開発者の幸せな生き方

Card image cap
アジャイルサムライ

プログラミング達人開発者への道

Card image cap
Rubyを作った男 まつもとゆきひろ

コードの世界 スーパー・プログラマになる14の思考法

ご提供 sponsor
 

Meee!(ミー)は、ビジネスからプライベート利用まで、個人のスキルを気軽に売り買いできるスキルマーケットです。カテゴリや居住地から、検索することが可能です。

 

ランゲージエクスチェンジは、ネイティブスピーカーと気軽にマッチングできる言語交換プラットフォームです。あなたの地元に住む外国人を探したり、留学や海外移住の前に、現地のネイティブスピーカーと繋がることもできます!

宣伝
 

りょすけトークchは、仕事や私生活をより豊にするYouTubeチャンネルです。文献(本、映画、論文)から役に立つ情報をまとめ、生涯にわたり役に立つ哲学をお届けしています。是非、チャンネル登録してみてね

-ホーム

Copyright© offブログ! , 2021 All Rights Reserved Powered by AFFINGER5.