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
610
Spice up your notifications/try!Swift25
noppefoxwolf
3
840
iOSの隠されたAPIを解明し、開発効率を向上させる方法/iOSDC24
noppefoxwolf
2
1.3k
今から理解するApp Intentエコシステム/WWDC24Recap
noppefoxwolf
0
74
既存アプリをvisionOS対応してリリースした話/visionOS LT vol5
noppefoxwolf
0
230
UIのブラックボックスを探る/iOSDC23
noppefoxwolf
3
5.1k
CoreGraphicsでドット絵を描こう/iOSDC22
noppefoxwolf
0
3.2k
ランタイムデバッグのススメ/iOSDC21
noppefoxwolf
1
5.6k
google/mediapipe で始めるARアプリ開発/iOSDC2020
noppefoxwolf
1
1.7k
Other Decks in Technology
See All in Technology
AI時代のPlaywright活用(システムテストを自動化する ー 実行エンジンにPla ywrightを選んだ理由)
ynisqa1988
2
890
2年前に削除したPHPクラスが、 ある日突然決済をエラーにした
ykagano
1
690
20260720_クラウド女子会×PyLadiesTokyoコラボ Amazon Bedrock ハンズオン用資料
yuuka51
1
100
41歳でAWSが好きすぎてITエンジニアになったおっさんの話
yama3133
1
710
「休む」重要さ
smt7174
5
1.3k
2026年のソフトウェア開発を考える(2026/07版) / Agentic Software Engineering 2026-07 Findy Edition
twada
PRO
16
6.3k
Network Firewallやっていき!
news_it_enj
0
240
誤解だらけの開発生産性 / Myths and Misconceptions about Developer Productivity
i35_267
2
960
人とエージェントが高め合う協業設計
kintotechdev
0
680
LLMやAIエージェントをソフトウェアに組み込むプラクティス
shibuiwilliam
2
440
Type-safe IaC for Dart
coborinai
0
180
生成 AI 時代にいま一度「問い合わせ」について考えてみる
kazzpapa3
1
110
Featured
See All Featured
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
340
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Making the Leap to Tech Lead
cromwellryan
135
10k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
750
The Curious Case for Waylosing
cassininazir
1
440
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.3k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
WCS-LA-2024
lcolladotor
0
730
Color Theory Basics | Prateek | Gurzu
gurzu
0
390
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
370
Skip the Path - Find Your Career Trail
mkilby
1
170
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