Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
よくある動画アプリのあれを実装したい。
Search
nakajijapan
May 28, 2014
Technology
0
2.7k
よくある動画アプリのあれを実装したい。
Instagram, Vine, SlideStory のような動画アプリで動画を保存する仕込みが気になったので実装しました。
nakajijapan
May 28, 2014
Tweet
Share
More Decks by nakajijapan
See All by nakajijapan
サービスにおけるDesign Systemの構築
nakajijapan
11
3.9k
Markdownをリアルタイムに解析する
nakajijapan
5
4.4k
Firebase Authorization
nakajijapan
0
290
Intoducing Izumo
nakajijapan
1
2k
Practical CloudKit
nakajijapan
1
1.8k
Introducing to Ajimi - プロダクトを味見していこう
nakajijapan
0
2.3k
Shari
nakajijapan
1
2.8k
Japan Apple Pay Development
nakajijapan
0
290
業務で絶対必要にならない技術
nakajijapan
0
860
Other Decks in Technology
See All in Technology
Strands AgentsとNova 2 SonicでS2Sを実践してみた
yama3133
0
440
Bedrock AgentCore Memoryの新機能 (Episode) を試してみた / try Bedrock AgentCore Memory Episodic functionarity
hoshi7_n
0
380
AIプラットフォームにおけるMLflowの利用について
lycorptech_jp
PRO
1
170
[デモです] NotebookLM で作ったスライドの例
kongmingstrap
0
160
re:Invent2025 3つの Frontier Agents を紹介 / introducing-3-frontier-agents
tomoki10
0
260
Databricks向けJupyter Kernelでデータサイエンティストの開発環境をAI-Readyにする / Data+AI World Tour Tokyo After Party
genda
1
560
Python 3.14 Overview
lycorptech_jp
PRO
1
120
Microsoft Agent 365 についてゆっくりじっくり理解する!
skmkzyk
0
380
Identity Management for Agentic AI 解説
fujie
0
110
チーリンについて
hirotomotaguchi
6
2.1k
シニアソフトウェアエンジニアになるためには
kworkdev
PRO
3
190
ActiveJobUpdates
igaiga
1
140
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
85
9.3k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Utilizing Notion as your number one productivity tool
mfonobong
2
180
Making the Leap to Tech Lead
cromwellryan
135
9.7k
WCS-LA-2024
lcolladotor
0
380
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.3k
Git: the NoSQL Database
bkeepers
PRO
432
66k
It's Worth the Effort
3n
187
29k
The Invisible Side of Design
smashingmag
302
51k
Raft: Consensus for Rubyists
vanstee
141
7.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.6k
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