Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AV Foundation
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
nakajijapan
February 01, 2014
Technology
830
4
Share
AV Foundation
心霊動画アプリ「もう一度ご覧いただこう」を作成してみて
Conference With Developers 2014
nakajijapan
February 01, 2014
More Decks by nakajijapan
See All by nakajijapan
サービスにおけるDesign Systemの構築
nakajijapan
11
4.1k
Markdownをリアルタイムに解析する
nakajijapan
5
4.6k
Firebase Authorization
nakajijapan
0
330
Intoducing Izumo
nakajijapan
1
2k
Practical CloudKit
nakajijapan
1
1.9k
Introducing to Ajimi - プロダクトを味見していこう
nakajijapan
0
2.4k
Shari
nakajijapan
1
3k
Japan Apple Pay Development
nakajijapan
0
330
業務で絶対必要にならない技術
nakajijapan
0
890
Other Decks in Technology
See All in Technology
脅威をエンジニアリングの糧にして:恐怖を乗り越えた先にあったもの / Turn threats into fuel for engineering: what lay beyond overcoming fear
nrslib
1
280
JavaScript実装の自作プログラミング言語をTypeScript実装に移行した話
keisukeikeda
1
150
キャリア25年目にしてTypeScript に出会うまで - 「型」を通じて振り返るプログラミング言語遍歴 / Meeting TypeScript After 25 Years in Tech - Looking Back at My Programming Language Journey Through "Types"
bitkey
PRO
2
280
コーディングエージェントはTypeScriptの 型エラーをどう自己修正しているのか
melonps
4
490
はじめてのAI-DLC
yoshidashingo
2
530
Claude Codeですべての日常業務を爆速化しよう!
minorun365
PRO
15
13k
『家族アルバム みてね』における インシデント対応との向き合い方 / Approach incident response in Family Album
kohbis
2
190
Python開発環境にハーネス適用を検討する
yuuka51
1
510
NFLコンペ2026 解法
lycorptech_jp
PRO
0
110
CloudFront VPCオリジンとVPC Latticeサービスの内部ALBをマルチアカウントで一元利用しよう
duelist2020jp
5
230
自称宇宙最速で不合格となったAIP-C01にリベンジを果たすべくAIで問題集アプリを作ってみた。
yama3133
0
140
生成AIに振り回されない 〜確率論と決定論の使い分け〜
shukob
0
110
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Ethics towards AI in product and experience design
skipperchong
2
280
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
150
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
The Limits of Empathy - UXLibs8
cassininazir
1
340
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.5k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.6k
Test your architecture with Archunit
thirion
1
2.2k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.2k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Deep Space Network (abreviated)
tonyrice
0
150
Transcript
"7'PVOEBUJPO ৺ྶಈըΞϓϦʮ͏Ұ͝ཡ͍ͨͩ͜͏ʯΛ࡞ͯ͠Έͯ !OBLBKJKBQBO
ࠓ͢͜ͱ w ࣗݾհ w ΞϓϦհ w "7'PVOEBUJPOΛ࣮ͬͨ͋Ε͜Ε w ॴײ
ࣗݾհ !OBLBKJKBQBO QBQFSCPZDP
!JTPEJOF
!JTPEJOF ςϨϏͰΔΑ͏ͳ৺ྶ൪ Έ͍ͨͳಈը࡞Γ͍ͨΜʙ
͍
None
IUUQPXLSJOGPNPWJF ͏Ұ͝ཡ͍ͨͩ͜͏ ৺ྶಈըΞϓϦ
ओͳػೳ w ಈըը w ಈըʹ৺ྶΛೖΕΔ w ಈըʹςϩοϓͱϫΠϓ w ಈըͷγνϡΤʔγϣϯʹ߹ΘͤͯφϨʔγϣϯ ΛೖΕΔ
w ιʔγϟϧڞ༗
w .FEJB1MBZFS'SBNFXPSL w 6*,JU ্ҐͷϑϨʔϜϫʔΫ
"7'PVOEBUJPO
ௐࠪ
ௐࠪ w "7'PVOEBUJPO1SPHSBNNJOH(VJEF w .PWJOHUP"7,JUBOE"7'PVOEBUJPOr w $PSF*NBHF&GGFDUTBOE5FDIOJRVFTr w
"EWBODFE&EJUJOHXJUI"7'PVOEBUJPOr
ߏ
εϩʔϞʔγϣϯಈը TFD TFD TFD φϨʔγϣϯԻ ϫΠϓ ը૾߹ ಈը݁߹ ಈը݁߹
࣮
ಈը݁߹
// Assetੜ AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:movieURL options:nil]; !
// CompositionTrackੜ AVMutableCompositionTrack* compositionVideoTrack; compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; ! // Ξηοτ͔ΒτϥοΫΛऔಘ AVAssetTrack *videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; ! // ઃఆ [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:videoTrack atTime:self.currentTimeDuration error:nil]; [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; // Assetੜ [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:self.currentTimeDuration error:nil]; self.currentTimeDuration = [mixComposition duration]; ! // Layer InstructionͷՃ AVMutableVideoCompositionLayerInstruction *layerInstruction; layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack]; ! [self.layerInstructions addObject:layerInstruction]; ϝσΟΞใΛอ࣋͠ɺͦͷใΛऔಘͰ͖Δ
// Assetੜ AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:movieURL options:nil]; !
// CompositionTrackੜ AVMutableCompositionTrack* compositionVideoTrack; compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; ! // Ξηοτ͔ΒτϥοΫΛऔಘ AVAssetTrack *videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; ! // ઃఆ [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:videoTrack atTime:self.currentTimeDuration error:nil]; [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; // Assetੜ [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:self.currentTimeDuration error:nil]; self.currentTimeDuration = [mixComposition duration]; ! // Layer InstructionͷՃ AVMutableVideoCompositionLayerInstruction *layerInstruction; layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack]; ! [self.layerInstructions addObject:layerInstruction]; ө૾ΛऔΓग़͢ ԻΛऔΓग़͢
// Assetੜ AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:movieURL options:nil]; !
// CompositionTrackੜ AVMutableCompositionTrack* compositionVideoTrack; compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; ! // Ξηοτ͔ΒτϥοΫΛऔಘ AVAssetTrack *videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; ! // ઃఆ [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:videoTrack atTime:self.currentTimeDuration error:nil]; [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; // Assetੜ [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:self.currentTimeDuration error:nil]; self.currentTimeDuration = [mixComposition duration]; ! // Layer InstructionͷՃ AVMutableVideoCompositionLayerInstruction *layerInstruction; layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack]; ! [self.layerInstructions addObject:layerInstruction]; ίϯϙδγϣϯΛΈཱͯΔ
ը૾ͷ߹ͱ Ξχϝʔγϣϯ
None
// generate parent layer CALayer* layerRoot = [CALayer layer]; CALayer*
layerVideo = [CALayer layer]; . . . . videoComp = [AVMutableVideoComposition videoComposition]; videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:layerVideo inLayer:layerRoot]; $"-BZFSʹ$"#BTJD"OJNBUJPOͰ ઃఆͨ͠ΞχϝʔγϣϯΛՃ͢Δ
ϫΠϓಈը
None
// Assetੜ AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:movieURL options:nil]; //
CompositionTrackੜ AVMutableCompositionTrack* compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; // Trackऔಘ AVAssetTrack* videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; ! // ઃఆ CMTime timeDuration; timeDuration = videoAsset.duration; ! [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, timeDuration) ofTrack:videoTrack atTime:kCMTimeZero error:nil]; [compositionVideoTrack setPreferredTransform:[videoTrack preferredTransform]]; AVMutableVideoCompositionLayerInstruction* layerInstruction; layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack]; [layerInstruction setTransform:CGAffineTransformConcat(scale, trnsration) atTime:kCMTimeZero]; ! [self.layerInstructions addObject:layerInstruction]; ΞϑΟϯม
εϩʔϞʔγϣϯ
// શମʹରͯ͠εϩʔϞʔγϣϯॲཧΛ͔͚Δ CMTime durationSlow = CMTimeSubtract(videoAsset.duration, CMTimeMake(9, 1)); [mixComposition scaleTimeRange:CMTimeRangeMake(CMTimeMake(19,
1), durationSlow) toDuration:CMTimeMake(durationSlow.value * 2.0, durationSlow.timescale)]; ࣮ࡍͷө૾Λ̎ഒͷ࣌ؒͰग़ྗͤ͞Δ
εϩʔϞʔγϣϯ ϫΠϓಈը ը૾ͷ߹ͱΞχϝʔγϣϯ ಈը݁߹ ࣮
"7'PVOEBUJPO
ॴײ w Ϋϥε໊͔ͬͨΓ࣮ྔ͕ଟͯ͘େมʂ w ͱ͍͑ઃܭ͢Β͍͠ w ใ͕গͳ͍ w ϋϚΔͱ໎ঢ়ଶ w
ࣄͰશ͘׆͔ͤͳ͍ʂʂʂ
4BNQMF.PWJF IUUQTXXXZPVUVCFDPNXBUDI WLKPXF43%* %FNP.PWJF IUUQTXXXZPVUVCFDPNXBUDI WSKUNK:6
5IBOLT