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
よくある動画アプリのあれを実装したい。
Search
nakajijapan
May 28, 2014
Technology
2.7k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
よくある動画アプリのあれを実装したい。
Instagram, Vine, SlideStory のような動画アプリで動画を保存する仕込みが気になったので実装しました。
nakajijapan
May 28, 2014
More Decks by nakajijapan
See All by nakajijapan
サービスにおけるDesign Systemの構築
nakajijapan
11
4.2k
Markdownをリアルタイムに解析する
nakajijapan
5
4.7k
Firebase Authorization
nakajijapan
0
340
Intoducing Izumo
nakajijapan
1
2.1k
Practical CloudKit
nakajijapan
1
1.9k
Introducing to Ajimi - プロダクトを味見していこう
nakajijapan
0
2.4k
Shari
nakajijapan
1
3k
Japan Apple Pay Development
nakajijapan
0
350
業務で絶対必要にならない技術
nakajijapan
0
910
Other Decks in Technology
See All in Technology
国家プロジェクトを支える「さくらONE」 大規模LLM開発におけるGPU障害を乗り越えるクラスター運用戦略
gpuunite_official
0
300
Bill One 開発エンジニア 紹介資料
sansan33
PRO
7
20k
サービス内で複数のOP・ASを連鎖させる(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
310
AIで変わるエンジニアの働き方(仮)
naoinaoi
0
570
AIレビュー時代に必要なのは、SLOで引く撤退ライン
nobuoooo
0
120
Digitization部 紹介資料
sansan33
PRO
2
7.7k
1.5時間を無駄にして学んだwsl2におけるaptとsnapの選択と仕組み
yosaka0123
0
450
あなたの知らないバージョン命名規則
sat
PRO
2
810
Dylib Hijacking on macOS: Dead or Alive?
patrickwardle
0
110
Claude Teamプランの コスト最適化を考える
rfdnxbro
0
740
OpenID for Verifiable Credentials 実装から見えた相互運用性確保までの道のり(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
320
暗号化?某ファイルストレージはどうなるの!? 3rd Partyとうまく付き合う秘密度ラベル設計
kasada
0
210
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
400
First, design no harm
axbom
PRO
2
1.3k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
400
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
290
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
67
57k
Accessibility Awareness
sabderemane
1
180
Balancing Empowerment & Direction
lara
6
1.2k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
210
Being A Developer After 40
akosma
91
590k
Transcript
BQQಓ !OBLBKJKBQBO Α͋͘Δಈը ΞϓϦͷ͋Ε Λ࣮͍ͨ͠
!OBLBKJKBQBO 4PGUXBSF&OHJOFFS (.01&1"#0JOD
৺ྶࣸਅΞϓϦ͓Θ͔Γ͍͚ͨͩͨͩΖ͏͔
৺ྶಈըΞϓϦ͏Ұ͝ཡ͍ͨͩ͜͏
"7'PVOEBUJPO ࠓճʂʂ
͋ͷಈըΛอଘ͢ΔΠ ϯλʔϑΣʔε͕ؾʹ ͳͬͨͷͰ࣮ͨ͠ɻ
༷
εΫϦʔϯΛλον ͨ͠ΒಈըΛอଘ։ ࢝ͯ͠εΫϦʔϯ͔ ΒΕͨΒอଘऴྃ
"7$BQUVSF4FTTJPO
"7$BQUVSF0VUQVU
"7$BQUVSF0VUQVU ɾ"7$BQUVSF.PWJF'JMF0VUQVU ɾ"7$BQUVSF4UJMM*NBHF0VUQVU ɾ"7$BQUVSF7JEFP%BUB0VUQVU ɾ"7$BQUVSF"VEJP%BUB0VUQVU
"7$BQUVSF0VUQVU ɾ"7$BQUVSF.PWJF'JMF0VUQVU ɾ'JMFT ɾ"7$BQUVSF4UJMM*NBHF0VUQVU ɾ*NBHF ɾ"7$BQUVSF7JEFP%BUB0VUQVU ɾ"7$BQUVSF"VEJP%BUB0VUQVU
ɾ-JWFEBUB
"7$BQUVSF0VUQVU ɾ"7$BQUVSF.PWJF'JMF0VUQVU ɾ'JMFT ɾ"7$BQUVSF4UJMM*NBHF0VUQVU ɾ*NBHF ɾ"7$BQUVSF7JEFP%BUB0VUQVU ɾ"7$BQUVSF"VEJP%BUB0VUQVU
ɾ-JWFEBUB
"7$BQUVSF"VEJP%BUB0VUQVU AVCaptureVideoDataOutputSampleBufferDelegate AVCaptureAudioDataOutputSampleBufferDelegate "7$BQUVSF7JEFP%BUB0VUQVU
#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate ! - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection { ! if (!CMSampleBufferDataIsReady(sampleBuffer)) { NSLog(@"sampleBuffer data is not ready"); } ! CMTime currentTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); ! if (self.touching) { ! // Video if ([captureOutput isKindOfClass:[AVCaptureVideoDataOutput class]]) { [self addSamplebuffer:sampleBuffer withWriterInput:(AVAssetWriterInput *)self.assetWriterInputVideo]; } // Audio else if ([captureOutput isKindOfClass:[AVCaptureAudioDataOutput class]]) { [self addSamplebuffer:sampleBuffer withWriterInput:(AVAssetWriterInput *)self.assetWriterInputAudio]; } ! } ! self.recordStartTime = currentTime; } AVCaptureVideoDataOutputSampleBufferDelegate AVCaptureAudioDataOutputSampleBufferDelegate
8SJUJOH
εΫϦʔϯΛλον ͨ͠ΒಈըΛอଘ։ ࢝ͯ͠εΫϦʔϯ͔ ΒΕͨΒอଘऴྃ
εΫϦʔϯΛλον ͨ͠ΒಈըΛอଘ։ ࢝ͯ͠εΫϦʔϯ͔ ΒΕͨΒอଘऴྃ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; -
(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
"7"TTFU8SJUFS "7"TTFU8SJUFS*OQVU
4UBSU8SJUJOH อଘରͷϑΝΠϧΛࢦఆͯ͠ॳظԽ ϝσΟΞλΠϓΛࢦఆ TFU&YQFDUT.FEJB%BUB*O3FBM5JNFΛ0/ʹ͢Δ "7"TTFU8SJUFSʹ"7"TTFU8SJUFS*OQVUΛΈࠐΉ ॻ͖ࠐΈ։࢝
4UBSU8SJUJOH // AVAssetWriter self.assetWriter = [AVAssetWriter assetWriterWithURL:self.outputURL fileType:AVFileTypeQuickTimeMovie error:&error]; !
! // movie NSDictionary *videoSetting = self.videoSettings; self.assetWriterInputVideo = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSetting]; [self.assetWriterInputVideo setExpectsMediaDataInRealTime:YES]; ! ! // audio NSDictionary *audioSetting = self.audioSettings; self.assetWriterInputAudio = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioSetting]; [self.assetWriterInputAudio setExpectsMediaDataInRealTime:YES]; ! ! [self.assetWriter addInput:self.assetWriterInputVideo]; [self.assetWriter addInput:self.assetWriterInputAudio]; ! // queue self.movieWritingQueue = dispatch_queue_create("Movie Writing Queue", DISPATCH_QUEUE_SERIAL); ! // Record [self.assetWriter startWriting]; [self.assetWriter startSessionAtSourceTime:self.recordStartTime];
4UBSU8SJUJOH // AVAssetWriter self.assetWriter = [AVAssetWriter assetWriterWithURL:self.outputURL fileType:AVFileTypeQuickTimeMovie error:&error]; !
! // movie NSDictionary *videoSetting = self.videoSettings; self.assetWriterInputVideo = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSetting]; [self.assetWriterInputVideo setExpectsMediaDataInRealTime:YES]; ! ! // audio NSDictionary *audioSetting = self.audioSettings; self.assetWriterInputAudio = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioSetting]; [self.assetWriterInputAudio setExpectsMediaDataInRealTime:YES]; ! ! [self.assetWriter addInput:self.assetWriterInputVideo]; [self.assetWriter addInput:self.assetWriterInputAudio]; ! // queue self.movieWritingQueue = dispatch_queue_create("Movie Writing Queue", DISPATCH_QUEUE_SERIAL); ! // Record [self.assetWriter startWriting]; [self.assetWriter startSessionAtSourceTime:self.recordStartTime];
4UBSU8SJUJOH // AVAssetWriter self.assetWriter = [AVAssetWriter assetWriterWithURL:self.outputURL fileType:AVFileTypeQuickTimeMovie error:&error]; !
! // movie NSDictionary *videoSetting = self.videoSettings; self.assetWriterInputVideo = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSetting]; [self.assetWriterInputVideo setExpectsMediaDataInRealTime:YES]; ! ! // audio NSDictionary *audioSetting = self.audioSettings; self.assetWriterInputAudio = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioSetting]; [self.assetWriterInputAudio setExpectsMediaDataInRealTime:YES]; ! ! [self.assetWriter addInput:self.assetWriterInputVideo]; [self.assetWriter addInput:self.assetWriterInputAudio]; ! // queue self.movieWritingQueue = dispatch_queue_create("Movie Writing Queue", DISPATCH_QUEUE_SERIAL); ! // Record [self.assetWriter startWriting]; [self.assetWriter startSessionAtSourceTime:self.recordStartTime];
4UBSU8SJUJOH // AVAssetWriter self.assetWriter = [AVAssetWriter assetWriterWithURL:self.outputURL fileType:AVFileTypeQuickTimeMovie error:&error]; !
! // movie NSDictionary *videoSetting = self.videoSettings; self.assetWriterInputVideo = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSetting]; [self.assetWriterInputVideo setExpectsMediaDataInRealTime:YES]; ! ! // audio NSDictionary *audioSetting = self.audioSettings; self.assetWriterInputAudio = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioSetting]; [self.assetWriterInputAudio setExpectsMediaDataInRealTime:YES]; ! ! [self.assetWriter addInput:self.assetWriterInputVideo]; [self.assetWriter addInput:self.assetWriterInputAudio]; ! // queue self.movieWritingQueue = dispatch_queue_create("Movie Writing Queue", DISPATCH_QUEUE_SERIAL); ! // Record [self.assetWriter startWriting]; [self.assetWriter startSessionAtSourceTime:self.recordStartTime];
4UBSU8SJUJOH // AVAssetWriter self.assetWriter = [AVAssetWriter assetWriterWithURL:self.outputURL fileType:AVFileTypeQuickTimeMovie error:&error]; !
! // movie NSDictionary *videoSetting = self.videoSettings; self.assetWriterInputVideo = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSetting]; [self.assetWriterInputVideo setExpectsMediaDataInRealTime:YES]; ! ! // audio NSDictionary *audioSetting = self.audioSettings; self.assetWriterInputAudio = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioSetting]; [self.assetWriterInputAudio setExpectsMediaDataInRealTime:YES]; ! ! [self.assetWriter addInput:self.assetWriterInputVideo]; [self.assetWriter addInput:self.assetWriterInputAudio]; ! // queue self.movieWritingQueue = dispatch_queue_create("Movie Writing Queue", DISPATCH_QUEUE_SERIAL); ! // Record [self.assetWriter startWriting]; [self.assetWriter startSessionAtSourceTime:self.recordStartTime];
4UBSU8SJUJOH - (void)addSamplebuffer:(CMSampleBufferRef)sampleBuffer withWriterInput:(AVAssetWriterInput *)assetWriterInput { CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer);
! CFRetain(sampleBuffer); CFRetain(formatDescription); dispatch_async(self.movieWritingQueue, ^{ ! if (_assetWriter.status == AVAssetWriterStatusWriting) { ! if (assetWriterInput.readyForMoreMediaData) { ! [assetWriterInput appendSampleBuffer:sampleBuffer]; ! } } ! CFRelease(sampleBuffer); CFRelease(formatDescription); }); }
$.4BNQMF#VGGFS3FG
$.4BNQMF#VGGFS3FG ɾ͋ΔϝσΟΞλΠϓͷαϯϓϧؚ͕·Εͨ$PSF'PVEBUJPO0CKFDUT ɹɾѹॖPSൺѹॖ ɾαϯϓϧ ɾશମͷத͔ΒऔΓग़ͨ͠Ұ෦ͷԿ͔
'JOJTI8SJUJOH ऴྃॲཧ ϑΝΠϧʹอଘ
'JOJTI8SJUJOH [self.assetWriterInputVideo markAsFinished]; [self.assetWriterInputAudio markAsFinished]; [self.assetWriter endSessionAtSourceTime:self.recordStartTime]; [self.assetWriter finishWritingWithCompletionHandler:^{ NSLog(@"self.assetWriter
finishWritingWithCompletionHandler"); [self.movieURLs addObject:self.outputURL]; NSLog(@"%@", self.movieURLs); }];
'JOJTI8SJUJOH [self.assetWriterInputVideo markAsFinished]; [self.assetWriterInputAudio markAsFinished]; [self.assetWriter endSessionAtSourceTime:self.recordStartTime]; [self.assetWriter finishWritingWithCompletionHandler:^{ NSLog(@"self.assetWriter
finishWritingWithCompletionHandler"); [self.movieURLs addObject:self.outputURL]; NSLog(@"%@", self.movieURLs); }];
͍͍ײ͡ʹग़དྷ্͕ͬͨ ͷͰެ։͠·ͨ͠ɻ
/,+.VMUJ.PWJF$BQUVSF7JFX IUUQTHJUIVCDPNOBLBKJKBQBO/,+.VMUJ.PWJF$BQUVSF7JFX
൚༻ੑ͕·ͩΓͳ͍ͷ Ͱʑॗʑͱվળͤͯ͞ ͍͖ͨͩ·͢ɻɻɻɻɻ
ࠂ͍ͤͯͩ͘͞͞
DPNNJOHTPPO
5IBOLT