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
630
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.7k
google/mediapipe で始めるARアプリ開発/iOSDC2020
noppefoxwolf
1
1.7k
Other Decks in Technology
See All in Technology
Pavlokで始める電撃駆動開発
sgrsn
0
190
20260804_Q4AzureUpdateBite_FabricDataAgentの精度を高める設計.pdf
matayuuu
1
130
同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す
kuroneko13
0
130
侵入は突然に 〜 IoTマルウェアと悪用される家庭の機器 ~ / When Intrusion Strikes: IoT Malware and the Abuse of Home Devices
nttcom
0
1.6k
【CEDEC2026】『GRANBLUE FANTASY: Relink - Endless Ragnarok』のバトル制作事例 ~最高のキャラゲーを目指して~
cygames
PRO
0
250
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
19k
クラウドセキュリティ入門 ~安全なクラウド利用のための基礎知識~
lhazy
13
8.6k
ブラウザ研修 2026
recruitengineers
PRO
6
940
Model Studio CLI × Token Plan
maigo999
0
150
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
4
24k
【CEDEC2026】ゲームシナリオライターを支援するAIツール開発の実践 ― 設計とプロンプトの工夫 ―
cygames
PRO
1
790
サイバー捜査員研修(後半)
nomizone
1
850
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
100
6.2k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.2k
Paper Plane
katiecoart
PRO
2
52k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
440
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
400
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
270
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
200
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