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
ライブ配信アプリのアイテム再生をMetalで実装する事になった話
Search
noppefoxwolf
September 02, 2018
Technology
12k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ライブ配信アプリのアイテム再生をMetalで実装する事になった話
noppefoxwolf
September 02, 2018
More Decks by noppefoxwolf
See All by noppefoxwolf
High performance GIF playback/iOSDC25
noppefoxwolf
1
650
Spice up your notifications/try!Swift25
noppefoxwolf
3
850
iOSの隠されたAPIを解明し、開発効率を向上させる方法/iOSDC24
noppefoxwolf
2
1.4k
今から理解するApp Intentエコシステム/WWDC24Recap
noppefoxwolf
0
78
既存アプリをvisionOS対応してリリースした話/visionOS LT vol5
noppefoxwolf
0
230
UIのブラックボックスを探る/iOSDC23
noppefoxwolf
3
5.2k
CoreGraphicsでドット絵を描こう/iOSDC22
noppefoxwolf
0
3.3k
ランタイムデバッグのススメ/iOSDC21
noppefoxwolf
1
5.7k
google/mediapipe で始めるARアプリ開発/iOSDC2020
noppefoxwolf
1
1.7k
Other Decks in Technology
See All in Technology
あなたの知らないバージョン命名規則
sat
PRO
2
870
顧客の要望は2次情報である 〜アンテナを張るFDEの構造論〜
noriakioji
5
1.1k
いかに伝えるか 〜新卒エンジニアの教育のための、ライトノベル活用の一例
ikedon
1
120
tamachi.goを支える技術
rymiyamoto
0
120
Claude Codeで開発以外の業務も爆速化しよう!
minorun365
PRO
12
9.3k
分割40%キーボードにスムーズに入門するには
hoto17296
1
210
dbt in Microsoft Fabric
ryomaru0825
0
320
現場の暗黙知を継承するAIエージェント — 対話から生まれる長期記憶と Skills
atsukish
0
180
DMMブックスのNext.js化を加速させるAI活用 / Migrating DMM Books to Next.js with AI
kentarom
0
250
Claude Codeの体系的な理解と知識のフック
oikon48
10
6.2k
AI駆動開発を組織で促すために
lycorptech_jp
PRO
7
9k
Microsoft MVP プログラムを紹介するから目指す人増えてくれ
tsubakimoto_s
0
160
Featured
See All Featured
For a Future-Friendly Web
brad_frost
183
10k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Statistics for Hackers
jakevdp
799
230k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Amusing Abliteration
ianozsvald
1
280
How to train your dragon (web standard)
notwaldorf
97
6.8k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
220
BBQ
matthewcrist
89
10k
Become a Pro
speakerdeck
PRO
31
6.2k
How to Talk to Developers About Accessibility
jct
2
530
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
220
Transcript
ϥΠϒ৴ΞϓϦͷΞΠςϜ࠶ੜΛ .FUBMͰ࣮͢Δࣄʹͳͬͨ J04%$+BQBO5SBDL# JPTEDC TIBSF
OPQQF ! גࣜձࣾσΟʔɾΤψɾΤʔ " ͖ͭͶ͔Θ͍͍ # ΞϓϦ։ൃ̎̌̍̌ʙ JPTEDC TIBSF
ࠓͷ ɾ1PDPDIBͷհ ɾΞΠςϜΤϑΣΫτͷ࠶ੜख๏ ɾ࠶ੜख๏ͷ࣮ൺֱ ɾ·ͱΊ JPTEDC TIBSF
ϥΠϒ৴ΞϓϦ1PDPDIBͷհ JPTEDC TIBSF
1PDPDIB w ϥΠϒ৴ΞϓϦ w ʙ w ߴੑೳͳඒഽɾඒإϑΟϧλʔ w ΞΠςϜʹΑΔίϛϡχέʔ γϣϯ
JPTEDC TIBSF
ΞΠςϜͷΤϑΣΫτͷ࠶ੜख๏ JPTEDC TIBSF
JPTEDC TIBSF
ΞΠςϜͷΤϑΣΫτ w º w GQT w ಁա৭͋Γ w ඵ JPTEDC
TIBSF
ΞΠςϜͷΤϑΣΫτΛJ04্Ͱ࠶ੜ͢Δʹ JPTEDC TIBSF
ᶃ"71MBZFSͰ࠶ੜ͢Δ let url = Bundle.main.url(forResource: "item_effect", withExtension: "mov")! let asset
= AVURLAsset(url: url) let item = AVPlayerItem(asset: asset) let player = AVPlayer(playerItem: item) let playerLayer = AVPlayerLayer(player: player) playerLayer.backgroundColor = UIColor.clear.cgColor view.layer.addSubLayer(playerLayer) player.play() JPTEDC TIBSF
"71MBZFS-BZFSͰɺಁաใͷ ͋ΔಈըΛѻ͏ࣄ͕Ͱ͖ͳ͍ɻ *NQPSUBOU 5IFWBMVFPGBQMBZFSMBZFS`T JOIFSJUFEDPOUFOUTQSPQFSUZJT PQBRVFBOETIPVMEOPUCF VTFE "71-BZFS-BZFSυΩϡϝ ϯτΑΓ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPO
BWGPVOEBUJPOBWQMBZFSMBZFS JPTEDC TIBSF
ᶄ6**NBHF7JFXͰ࠶ੜ͢Δ let imageView = UIImageView() let images = (0...300).compactMap({ UIImage(named:
"\($0).png") }) imageView.animationImages = images imageView.startAnimating() JPTEDC TIBSF
ᶄ6**NBHF7JFXͰ࠶ੜ͢Δ $ ffmpeg -i input.mov images/output_%04d.png JPTEDC TIBSF
ᶄ6**NBHF7JFXͰ࠶ੜ͢Δ $ ffmpeg -i input.mov images/output_%04d.png $ du -sh ./images
302M ./images ☺ JPTEDC TIBSF
ᶄ6**NBHF7JFXͰ࠶ੜ͢Δ JPTEDC TIBSF
ᶄ6**NBHF7JFXͰ࠶ੜ͢Δ Message from debugger: Terminated due to memory issue ͰΫϥογϡ
JPTEDC TIBSF
ݕূ͔Β͔ͬͨ̎ͭͷ՝ײ w ಈըࣗମͷ༰ྔ w ࠶ੜύϑΥʔϚϯε JPTEDC TIBSF
ಈըࣗମͷ༰ྔ ඇѹॖNPWϑΝΠϧ .# ࿈൪1/(ϑΝΠϧ .# ѹॖ͢Δඞཁ͕͋Δ JPTEDC TIBSF
ϑΝΠϧͷѹॖͰඞਢͳཁ݅ w ಁաใΛ͍࣋ͬͯΔ w GQTΛམͱ͞ͳ͍ w ॎԣͷαΠζΛมߋ͠ͳ͍ JPTEDC TIBSF
ϑΥʔϚοτ ಁա ѹॖ σίʔυෛՙ BQOH ˓ .# º XFCQ ˓
.# º TG XFCN ˓ ,# º NQ º .# ˓ I "1/(༰ྔͷ࣌Ͱෆ࠾༻ͩͬͨͷͰະଌఆɻ8&#.σίʔμ͕ແͦ͞͏ͳͷͰະଌఆ WQXJUIBMQIB JPTEDC TIBSF
NQΛͳΜͱ͔ಁաʹରԠग़དྷͳ͍͔ ͜͜ͰɺੲήʔϜΛ࡞͍ͬͯͨ࣌ͷ͜ͱΛࢥ͍ग़͢ JPTEDC TIBSF
JPTEDC TIBSF
JPTEDC TIBSF
ಁա߹ͱඳը ͔͜͜ΒɺಁաಈըϓϨʔϠʔΛ࣮͍ͯ͘͠ w $PSF*NBHF w 0QFO(-&4 w .FUBM ΛͦΕͧΕͬͯ࡞ͬͨ݁ՌΛൺֱ͠·͢ɻ JPTEDC
TIBSF
ಁա߹ͱඳը w º w GQT w ಁա৭ͳ͠ w ඵ w
NQ JPTEDC TIBSF
$*'JMUFSΛͬͨ߹ $*'JMUFS J04 Ҏ্ͷϓϦηοτϑΟϧλ $16͔(16Ͱॲཧ JPTEDC TIBSF
$*'JMUFSΛͬͨ߹ $*'JMUFS J04 Ҏ্ͷϓϦηοτϑΟϧλ $16͔(16Ͱॲཧ $*#MFOE8JUI.BTL ΞϧϑΝͷը૾Λͬͯಁա IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPO DPSFJNBHFDJpMUFS JPTEDC
TIBSF
$*'JMUFSΛͬͨ߹ let filter = CIFilter(name: "CIBlendWithMask")! filter.setValue(baseCIImage, forKey: kCIInputImageKey) filter.setValue(alphaCIImage,
forKey: kCIInputMaskImageKey) let filteredImage = filter.outputImage! let image = UIImage(ciImage: filteredImage) imageView.image = image JPTEDC TIBSF
J1IPOFDGQT JPTEDC TIBSF
0QFO(-&4Λͬͨ߹ͱඳը $"&"(--BZFS J04r (16Ͱॲཧ JPTEDC TIBSF
0QFO(-&45*14 JPTEDC TIBSF
0QFO(-&45*14 &"(-$POUFYU ςΫενϟΤϥʔঢ়ଶͳͲΛཧ JPTEDC TIBSF
0QFO(-&45*14 // ͲͷίϯςΩετͰಈ࡞͢Δ͔ෆఆ glDisable(GLenum(GL_DEPTH_TEST)) // ར༻͢ΔcontextΛઃఆ EAGLContext.setCurrent(context) // ↑Ͱࢦఆͨ͠contextͰ࣮ߦ͞ΕΔ glDisable(GLenum(GL_DEPTH_TEST))
JPTEDC TIBSF
0QFO(-&45*14 glGetError() ྫɿGL_INVALID_ENUM ແޮͳFOVNΛࢦఆ͍ͯ͠Δɻ JPTEDC TIBSF
0QFO(-&45*14 9DPEFͰϒϨʔΫϙΠϯτΛࠐΉ͜ͱՄ JPTEDC TIBSF
0QFO(-&4Λͬͨ߹ͱඳը $PSF*NBHF 0QFO(-&4 $**NBHF ςΫενϟ $*'JMUFS ϑϥάϝϯτγΣʔμ 6**NBHF7JFX Ϩϯμϥ $"&"(--BZFS
JPTEDC TIBSF
0QFO(-&4Λͬͨ߹ͱඳը varying lowp vec2 textureCoordinate; uniform sampler2D videoFrame; void main()
{ // ϕʔεͷ৭ͷx lowp float x = textureCoordinate.x / 2.0; // ϕʔε৭ͷऔಘ lowp vec2 baseCoord = vec2(x, textureCoordinate.y); lowp vec4 baseColor = texture2D(videoFrame, baseCoord); // alphaͷऔಘ lowp vec2 alphaCoord = vec2(x + 0.5, textureCoordinate.y); lowp vec4 alphaColor = texture2D(videoFrame, alphaCoord); // RGBϕʔε৭ɺAalphaΛར༻͢Δ gl_FragColor = vec4(baseColor.r, baseColor.g, baseColor.b, alphaColor.r); } JPTEDC TIBSF
HM@'SBH$PMPSWFD CBTF$PMPSS CBTF$PMPSH CBTF$PMPSC BMQIB$PMPSS JPTEDC TIBSF
0QFO(-&4Λͬͨ߹ͱඳը J1IPOFD㲈GQT JPTEDC TIBSF
͔͠͠ʜ JPTEDC TIBSF
JPTEDC TIBSF
88%$Ͱಥવͷ%FQSFDBUFEɻ ϥΠϒ৴ΞϓϦͷΞΠςϜ࠶ੜΛ.FUBMͰ࣮͢Δ ࣄʹͳͬͨ ແࣄλΠτϧճऩ ☺ JPTEDC TIBSF
.FUBMͰॻ͍ͯΈ·ͨ͠ JPTEDC TIBSF
.FUBMͷར w γΣʔμʔͷࣄલίϯύΠϧ w (16$16ͷڞ༗ϝϞϦۭؒ w (16ͷ໋ྩΛ·ͱΊͯૹΕΔ FUD %ΛΰϦΰϦʹ͏ਓ͘Β͍͔͠تͳ͍ʜ JPTEDC
TIBSF
.FUBMΛͬͯΈͯײͨ͡ར (16ϓϩάϥϛϯάॳ৺ऀʹ༏͍͠.FUBM w (16Λ৮Δ্Ͱॻ͖͍͢*' w ཧղΛਂΊΔ্ͰॏཁͳσόοΨʔ JPTEDC TIBSF
.FUBMΛͬͯΈͯײͨ͡ར let desc = MTLRenderPipelineDescriptor() desc.vertexFunction = library.makeFunction(name: vertexFunctionName) desc.fragmentFunction
= library.makeFunction(name: fragmentFunctionName) desc.colorAttachments[0].pixelFormat = pixelFormat 4XJGU0CK$Ͱॻ͖͍͢Ϟμϯͳ*' ίϯύΠϧ࣌ʹ͕ൃ͍֮͢͠ɻ JPTEDC TIBSF
.FUBMΛͬͯΈͯײͨ͡ར γΣʔμʔͷΤϥʔίϯύΠϧ࣌ʹڭ͑ͯ͘ΕΔ JPTEDC TIBSF
.FUBMΛͬͯΈͯײͨ͡ར w (16Λ৮Δ্Ͱॻ͖͍͢*' w ཧղΛਂΊΔ্ͰॏཁͳσόοΨʔ σόοΨʔʹ͍ͭͯ͜ͷޙհ͠·͢ɻ JPTEDC TIBSF
.FUBMͰॻ͍ͯΈ·ͨ͠ ͜ΕΒͷརΛ౿·͑ͯɺ.FUBMͰ ॻ͍ͯΈ·ͨ͠ɻ అ͞Μͷ.FUBMೖ͕ಡΈ͘͢ ͓ͯ͢͢ΊͰ͢ɻ JPTEDC TIBSF
J1IPOFT㲈GQT JPTEDC TIBSF
.FUBMͰॻ͍ͯΈ·ͨ͠ (16'SBNF$BQUVSF w ΧϝϥϚʔΫͷϘλϯ JPTEDC TIBSF
JPTEDC TIBSF
֤ςΫενϟΛQOHUJ⒎Ͱॻ͖ग़͢ࣄͰ͖·͢ɻ JPTEDC TIBSF
JPTEDC TIBSF
0QFO(-&4൛ͷ(16'SBNF$BQUSVF*OTUSVNFOUT ɺࣗͷڥͰಈ͔ͳ͘ͳ͍ͬͯ·ͨ͠ JPTEDC TIBSF
.FUBMͷ*OTUSVNFOUTવར༻Ͱ͖·͢ɻ JPTEDC TIBSF
·ͱΊ JPTEDC TIBSF
ΞϓϦΤϯδχΞ.FUBM৮Δ͖͔ w ࢥͬͨΑΓ͘͠ແ͘ɺཧղ͍͢͠ੈք w "3,JU$PSF.-ʹܨ͕Δٕज़ JPTEDC TIBSF
.FUBMͰ࣮͢Δඞཁ͋Δͷ͔ w ը૾ฤूͳΒ$*'JMUFSΛ·ͣݕ౼ w .FUBMͷσϝϦοτΛཧղ্ͨ͠Ͱ࠾༻͢Δ͖ JPTEDC TIBSF
.FUBMͰ࣮͢Δ্Ͱͷҙ w J04ະຬͷσόΠεʹ.FUBMඇରԠͷ͕͋Γ ·͢ w γϛϡϨʔλ.FUBMඇରԠͰ͢ MTLCreateSystemDefaultDevice() != nil JPTEDC
TIBSF
.FUBMͰ࣮͢Δ্Ͱͷҙ γϛϡϨʔλͰϏϧυͰ͖ͳ͍ࣄ͋Γ·͢ Ұ෦ͷϔϧύʔγϛϡϨʔλ4%,ʹؚ·Ε·ͤΜ w $".FUBM%SBXBCMF w $".FUBM-BZFS IUUQTHJTUHJUIVCDPNOPQQFGPYXPMGGBBBDCCEECG JPTEDC TIBSF
1PDPDIBͰ .FUBMͰ࣮͠·͕ͨ͠ʜ w ࠓ0QFO(-&4൛Λ͍ͬͯ·͢ w J04αϙʔτ͢ΔͨΊ w γϛϡϨʔλ͍ͬͯΔ 0QFO(-&4͕ഇࢭ͞ΕͨΒͲ͏͢Δͷʁ ˠͦͷࠒʹJ04ରԠ͠ͳ͍ͩΖ͏͠ɺγϛϡϨʔλͰ.FUBM͕ಈ͘Α͏ʹ
ͳ͍ͬͯ·͢ʂʂʢଟͶʣ JPTEDC TIBSF
4PVSDF$PEF ಁաॲཧΛࢪͯ͠࠶ੜ͢ΔϓϨʔϠʔϥΠϒϥϦΛ࡞͍ͬͯ·͢ JPTEDC TIBSF
4PVSDF$PEF w OPQQFGPYXPMG,JUTVOFCJ w OPQQFGPYXPMG,
[email protected]
! " !
JPTEDC TIBSF
! ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ "TLUIFTQFBLFS %F/"4QFBLFS-PVOHF JPTEDC TIBSF