プリッカソン第3回やってみた!

prickathon.connpass.com

アイドル×ハッカソンアイマスハッカソンだけじゃない,プリパラハッカソンも(本当に)あるんだ,ということで,第2回につづき2回目の参加をしてきた。

f:id:banjun:20180521002542j:plain  道中のコンビニでプリパラっぽいおやつを探す。梅ののど飴とパクチープリッツ。時間ぴったり。

f:id:banjun:20180521002606j:plain  会場はサポーターズの広い会議室。主催の@takanakahiko さんが遅れているということで,プロジェクター接続確認とかを。ホワイトボードがあるが絵もなにもない!なかったら描くしかない!ということで描いておいた。この1ヶ月くらい,夜はコードも書かず(ハッカソンの準備すればいいのに・・・),pixiv senseiやってたからな・・・1ヶ月でやれば有料会員も1ヶ月で済むとかそういう。 ぼちぼち人が揃って自己紹介タイムして,日曜なのでプリ☆チャンをみる。あにてれ最高。

ハッカソンのネタは,前回に引きつづきで im@sparql インスパイアのプリパラDBを進められそうな雰囲気だったので,ネイティブクライアント側の続きから攻めてみる。 Firebase最近ちょっとチェックしたこともあり,どうやらjsonにRESTアクセスするよりも,Firebase SDKから触るほうが,異なるパラダイムを体験できて正しいということのようだったので,それを試してみる。 クライアント機能としてなにを実現するか,というのはネタ出しも難しいので,DBをFirebase SDKでみられるようにする,という素振りをやることにした。

Access to Firebase Realtime DB by banjun · Pull Request #1 · prickathon/PriparaDB-song-ios · GitHub

Realtime DBというとおり(なのか?),リクエストを投げておけばDB側が更新されたときに自動的に更新内容が再取得されるようになった。さすがFirebaseの力という感じがある。DB側はまだ手でJSONを書き足していたけど,追加するとiOSアプリ側に降ってくるのに良さがある。プリパラのサブタイリストに各話を追加すると,謎の仕組みによりiOSアプリ側が勝手に再描画される。 自動再描画は通信部分はFirebase SDK,データ保持はReactiveSwift,差分更新はBigDiffer,ということで,新規要素はFirebaseのシンプルなところだけで,他は迷いなくいける。BigDiffer最近つくっておいて便利だった。マルチセクション差分更新やれるし。GitHub - banjun/BigDiffer: diff & patch for UITableView with large number of rows (changes between 0~5000)

Firebase SDKの返り値自体はSwiftyJSONぽさのある型の期待できない,Codable JSONよりだいぶ劣るダサさがあったのだが,誰かやっているだろう・・と探すとCodableFirebaseというのがちょうどリリース更新されていたので,それを噛ませて,困ることはなかった。 GitHub - alickbass/CodableFirebase: Use Codable with Firebase

f:id:banjun:20180521002625j:plain

 実際のところは,クライアントで,リアルタイム更新反映が必要なユースケースは,ゼロかもしれない。そのへんが,ただのRESTのほうが単に便利なのではという気がしなくもないという迷いが残ったまま。 Firebaseではクライアントサイドジョインをするのです,という話もみたので,シリーズ名(=セクションに表示している,「キラっとプリ☆チャン」「プリパラ」)を引いてくるところを,UITableViewのセクション表示をトリガーに(=lazyに),シリーズのキーからFirebaseにリクエストして取得,という練習もしてみた。そもそも速すぎて効果は謎だし,たくさん同じリクエストしたときにキャッシュされたりするのだろうか,とかも未調査のままである。

Firebase Realtime DB側もちょっとだけ。orderbyとかフィルタにはindexを貼るといいというログが出るとか,そもそもRealtime DBはorderとフィルタは重ねられないとか,そういう知見を得ることとなった。indexのルールをbolt書こうとしてハマりまくったPRたち。やたらかわいい。

enable query by series on episodes by banjun · Pull Request #1 · prickathon/priparaDB-firebase · GitHub

index should be placed in path in bolt by banjun · Pull Request #2 · prickathon/priparaDB-firebase · GitHub

Fix: boltから生成されたルールで$...keyが二つになるとデプロイできない by banjun · Pull Request #3 · prickathon/priparaDB-firebase · GitHub

indexの位置を/episodes直下に上げる(pathの数自体を増やさずに) by banjun · Pull Request #5 · prickathon/priparaDB-firebase · GitHub

前回のハッカソンは2ヶ月前,ちょうど,プリパラ最終回の前の日曜日だった。今回までのあいだにはプリパラが終わりプリ☆チャンが始まりプリパズが終わり映画が始まり・・いろいろあったが,プリ☆チャンと並行して,Vtuberが流行りVR出社が流行り(?),周辺界隈は技術的にも見どころが多い。このへんの技術を組み合わせていくとプリ☆チャンの時代にはマッチしそうだが・・・調査とか準備次第かな・・・。

おまけ: 会議室の入り口ではSuicaレッドブル買えてちょうべんり。

f:id:banjun:20180521002643j:plain  とても快適な会場だったので次も貸していただけるならやりたい・・・!が,会場キャパに対して人数が足りていないのはもったいない。。次はここを(アイドルで)いっぱいにしてみせます!ってやりたいね。

🍓2017年振り返り

f:id:banjun:20171230012719p:plain

勉強会

昨年は東京に来たばかりで,勉強会に参加しはじめた,というところで数はほとんどなかった。今年は積極的に行こうとした。 昨年末のアイマスハッカソンで初LT経験したので,今年は2回登壇を達成した(前年比でみれば,2倍である‥)。 参加した勉強会は次のとおり (🎤=登壇) 。参加費がそこそこのものは業務扱いにしてもらった。

1/21 Cookpad TechConf 2017
3/2-4 try! Swift Tokyo 2017
3/7 try! Swift Tokyo 2017 Aftershow
4/15 Swift Tweets 2017 Spring
4/17 AKIBA.swift 一周年記念勉強会!
4/26 WWDC Pre Party 2017 🎤 二度のWWDC出張であったことと変えたこと / thoughts in my 2 WWDC & what's changed for the second flight // Speaker Deck
5/17 アイマスエンジニア MeetUp in Tokyo
6/19 CA.swift #3 WWDC17 報告会
6/21 WWDC After Party 2017
6/27 GEEK GARAGE iOS vol3
7/22 Swift Tweets 2017 Summer
9/15-17 iOSDC JAPAN 2017
10/13 iOSDC 2017 Reject Conference days1
12/5 iOS Test Night #6 - 1周年 -
12/16 アイマスハッカソン2017 🎤 PhotoStudioPlayerをつくる技術 / PhotoStudioPlayer Technologies // Speaker Deck

勉強会に参加するにつれて,だんだんと知り合いが増えていくのは,とてもよいフィードバックループだった。勉強会で他の方を紹介してくれる・私を他の方に紹介してくれる方々には本当にいつも感謝しております。 年の中盤くらいまでは,名刺消費ペースが高かったが,終盤はわりと知り合いと話していたので,ペースが下がった。それはそれで楽しいが,また少し勇気を出してみたらいいかもしれない。iOSDCで運用されていたパックマンルール(数人で話すときに,話の環を1箇所あけておくことで,他の人が入ってきやすいようにする)は,良いものだったので,他の界隈でも普及してほしい。

今年のLT登壇は,緊張せずに楽しく喋る,という目標レベルだった。次は聴きやすいように喋りたいなぁと,YouTube Liveのアーカイブをみて思った。そうだ,YouTube Live顔出し配信実績解除も今年だった。

ライブ

今年はライブビューイング・ディレイビューイングを含めて,26日間ライブに参加した。その全てを,Apple Watch シリーズ2またはシリーズ3のワークアウトを使って心拍数を記録した。

f:id:banjun:20171229225703p:plain

心拍数を月別でみると,ライブにいった月の心拍数は高く,Watchの計測限界215に当たっている月もいくつかある。

f:id:banjun:20171229230050j:plain

日別でみると,2週間に二日ずつ心拍数の高い日があるのが今年の特徴である。特に8月は忙しかった。

f:id:banjun:20171229230054j:plain

アイマス

主にシンデレラ5thツアーを @tappi417 と一緒に回った。ディレイも含めて全日程(16日間)に参加した。宮城(両日)・大阪(Day1)・静岡(両日)・幕張(Day2)・福岡(両日)・SSA(両日)は現地参加できた。不思議なもので,どの回でも担当のありすを感じることができた。出演していたり,MCで言及されていたり,ソロのおねシン・ももありハイファイのCDが告知されたり,誕生日だったり。

ツアーの参加費用,チケット・物販・移動宿泊費・もろもろ,をまとめると,結構すごいことになっていた。iMac Proくらいは犠牲になったのだ‥?

アイマスハッカソンアイマストドンのおかげで,ライブ会場でいろいろな方と出会うこともできた。最初の宮城のときは,アイマスハッカソンノベルティのクリアファイルを目印に出会う,みたいなことをやっていた。
(アイマスハッカソンで言うとそれだけではない。 try! Swiftでもアイマスハッカソン経由の知り合いと複数出会うこととなった)
(さらにアイマストドンだと‥‥15年くらい前にiTools.jpというユーザーグループでiChatにいた人とライブ会場で再会することとなった。またオンラインチャットか‥!という感じでおもしろいですねアイマストドン)

アイマストドンといえば,SSAでフラスタが企画されたので,のっかった。初めて会場で自分の名前をみた。イラストもアイマストドンで分担して描いていたようで,良い試みだと思う。イラスト描けるようになりたい。

f:id:banjun:20171229235105j:plain

今年はミリシタが来たので,ミリオンライブにも入門した。最初のライブは武道館のハッチポッチだった。予習不能ということで,(鍋だけに)フタを開けてみれば765の古い曲だけ知っていた,という感じだった。2週後にディレイビューイングがあるということで,それまでにCDほほぼ全て買い集めて復習して,2週後を迎えた。まさにハッチポッチは二度おいしかった。

プリパラ

1月のミュージカルから。平日の昼間だった。座席の通路も使うミュージカルで,通路から近いランウェイシートに座っていた。近い。プリパラのライブでちょっと違和感があるのはメイキングドラマの部分だが,ミュージカルにして小道具とかで演出してしまえば相性良いのだなぁと思った。退場時にi☆Risメンバーとハイタッチがついている回で,列の進みは遅いので,ゆっくりスッと手を合わせる感じだったが,不意にぎゅっとされてドキドキした。それからしばらくは会う人に「ハイタッチは,やばい」と言っていた。

サマーライブ・ウインターライブはアイドルタイムプリパラ。夏はオールスタンディングだが整理番号30以内という神ポジションを手に入れ,近い,かわいい・・,とやっていた。冬の席はふつうだった。ライブにいくと久保田未夢がかわいいと思う。伊達朱里紗は特に冬は本当に楽しそうでよかった。今年のマイブーム。

夏は1.5hスタンディング,冬は席があるが2h休みなしライブ,ということで,平均心拍数でいうと今年のトップ3のうち2つをしめる。

💓159 プリパラサマーライブ (2h強の平均) on 8/6
💓149 シンデレラ5th静岡Day1 (3h強の平均) on 6/24
💓147 プリパラウインターライブ (3h弱の平均) on 12/10

バンドリ

ガルパからバンドリへ。はっしーのドラムみたいじゃん?ってチケット取った。ミリオンもはじめたので,あいみんのギターもみたいじゃん?ってなってそこもよかった。 やはり,1000回潤んだ空,がちゃんと聴きたいのだが‥演奏も難しいんだろうなぁとは思う。がんばってほしい。

KOTOKO

id:mzpKOTOKOライブに誘われて行った。そこまで曲知っているわけではないし‥と過去のセトリで予習してみると,聴いたら分かるやつだった!,というのがいくつも出てきてびびっていた。 とはいえ来たら完全にやばいのはLeaf ticketかImaginary affairだけだし,と言っていたところ,Leaf ticketが来て大変だった。MCで2000年ごろのインターネットの話がでるのも心にくる。kotoko.ddo.jp...あれはだれがやっていたのかなぁ。

つくったもの・描いたもの

アプリとかライブラリ

Touch Barにアイマストドンのローカルタイムラインをどんどん流すやつ

imastodon.net

マストドンまわりはクライアントつくるのもたのしくて良い。なにか試したい技術があるときに,マストドンクライアントでやってみるか的なサンドボックス的な使いかたもできる。というわけでそんなクライアントを書いた。

GitHub - banjun/imastodon: mastodon client for iOS

iPhone XのSafe Area対応とかもこのへんで試しながらやっていたし,APIはtry! Swiftで話を聞いたAPI Blueprintを起こしてみて,生成した。API Blueprintから,型がきちんと付いたクライアントを生成する,SwiftBeakerというコード生成ツールもつくった。

GitHub - banjun/SwiftBeaker: Swift client generator for API Blueprint

マストドンのストリミーングAPIはWebsocketのほかにServer Sent Eventsも用意されている。しばらくはinaka/EventSourceをつかっていたが,PRが放置されるというのもあり,ReactiveSwiftとパーサコンビネータFootlessParserをつかって独自のSSEパーサーをつくった。

GitHub - banjun/ReactiveSSE: Server Sent Events (SSE) parser operators for ReactiveSwift

ReactiveSwiftは今年試した技術のなかで一番効果があった技術かもしれない。

デレステにフォトスタジオが搭載されてからは, PhotoStudioPlayerというアプリをつくった。

f:id:banjun:20171230000819p:plain

これはブログ記事にもしたし,アイマスハッカソンで発表もしてきた。 デレステフォトスタジオのリアルタイム透過プレイヤーをつくった - ツバメになったバリスタ

PhotoStudioPlayerは今までで一番反響のあるツイートとなった。 アプリアイコンは後からSketchで描いた。Pull Requestもいままでになくたくさん,複数の人からもらえて,github★も71まで増えた。これのおかげで,githubのTrending Swift Developerで,少なくも23位までは上がっているのを確認できた。

アイマスハッカソンでは, id:mzp と一緒に,ライブで記録した心拍数を,ライブBDの再生時にWatchのhaptick feedbackで再現する,というアイディアの,最初のコンセプト実装をつくった。

mzp.hatenablog.com

誕生日イラスト

Apple Pencilを買ってから,絵を描けるようになりたいと思っている(継続)。担当アイドルの誕生日イラストを描く,というのも一度やってみたかったので,今年挑戦した。橘ありすの誕生日がシンデレラ5th福岡の翌日だったので,当日の宿から投稿できるように準備していった。すべてiPadのProcreateとApple Pencilで描いていて,その作業時間によれば延べ22時間かかっている。

www.pixiv.net

当日は博多のキルフェボンでいちごを食べた。

P名刺

アイマスライブをとおして,こんなにP名刺をつかうものなのかと思った。自分のP名刺も作りたかったが,製作もさまざまな判断が必要で躊躇していた。今年のアイマスライブがおわって一段落してからやっと着手しつくった。ライブではもらうばかりだったが,最後にアイマスハッカソン2017までには間に合わせられた。

f:id:banjun:20171230001805j:plain

他のOSS活動

あんなにライブに行っていたのに,コントリビューションカレンダーは昨年の361から増えて444。そんなにやったかなという感覚だが,数でみるとかなりいい増加にみえる。

f:id:banjun:20171229222212p:plain

昼のお仕事のほうでは,3ヶ月に1回は外部にPRするという目標があった。これはCookpadの勉強会(かなにか)で,「社内外のエンジニアに貢献する」という観点があって良いというところから立てた。 結果としてPull Requestを12個出せて,うち8がマージされた。

performance patch for AEXMLElement.subscript by banjun · Pull Request #99 · tadija/AEXML · GitHub
better performance in accessing children by tag name by banjun · Pull Request #51 · cezheng/Fuzi · GitHub
Fix redefinition of module RSDayFlow error by banjun · Pull Request #121 · ruslanskorb/RSDayFlow · GitHub
Fix unwanted omitting events right after commented lines by banjun · Pull Request #75 · inaka/EventSource · GitHub
Fix infinite retry for 404 status code by banjun · Pull Request #76 · inaka/EventSource · GitHub
Fix nil headers/footers of sections are displayed in FormViewController in Xcode 9 by banjun · Pull Request #1214 · xmartlabs/Eureka · GitHub
Swift 4 Support by banjun · Pull Request #10 · kareman/FootlessParser · GitHub
podspec for iOS by banjun · Pull Request #11 · kareman/FootlessParser · GitHub
Fix waitForView cannot find UITableViewCell or label, and results in UITableView on iOS 11 by banjun · Pull Request #1010 · kif-framework/KIF · GitHub
Fix firstChild with namespace crashes parsing sibling non-namespaced nodes by banjun · Pull Request #73 · cezheng/Fuzi · GitHub
Runtime crash with Xcode 9.1 · Issue #22 · 1024jp/GzipSwift · GitHub
Fix random runtime crash processing discontiguous data by banjun · Pull Request #24 · 1024jp/GzipSwift · GitHub
Fix FieldCell titleLabel layout can overlap to its value label by banjun · Pull Request #1344 · xmartlabs/Eureka · GitHub

同名のpodが既に出てるがどうしたらいいのか?みたいな周辺のサポートまで広がることもあり,経験のバリエーションが増えた。Pull Requestを出すこと自体も経験値が必要で,次の経験値を生むので,継続していきたい。

SwiftBeakerをつくって公開していたので,Swagger Codegenに対するアドバイスを求められメールで議論するようなこともあった。

Feedback on Swift API client generator · Issue #5761 · swagger-api/swagger-codegen · GitHub

そして今年は‥Swift自体には特に貢献しなかったような‥?来年はがんばる。

🍓いちご

今年食べたいちご・いちごの食べ物・いちごの飲み物の写真を写真ライブラリから拾ってきたら,186あった。

f:id:banjun:20171230004709j:plain

シンデレラ5thで各地にいったので,いろんなところでいちごを食べた。

f:id:banjun:20171230004812p:plain

次のステージへ

2017年は勉強会とアイマスという軸をベースに,さまざまな活動量を上げられた年となった。 自分のなかでは新しいことへのチャレンジがたくさん含まれていたのは,いい方向に進めたということだと思う。

f:id:banjun:20171229230556j:plain

(2月の新宿駅のデレマス広告,これからもプロデュース活動しようという気持ちになる)

2018年もアイマスですよ!

デレステフォトスタジオのリアルタイム透過プレイヤーをつくった

Touch Barで卯月をつんつんしてから一年が経った。 今年の新ネタはiPhone X関連かと思っていながら予約に負けたので,穏やかな心でイープラスに勝利しつつ文化の日となった。

というわけで今日は文化の日につくった,↓のツイートにあるデレステフォトスタジオのリアルタイム透過プレイヤー,PhotoStudioPlayerの話を書く。

きっかけ

ちょうど前日に,デレステにフォトスタジオという新機能の追加が発表されたところだった。

カメラの視点が自由に回せてズームインアウトもできるということで,従来カメラに対しては(縦化以外では)なにもできなかったデレステの,スクショの幅が増えた。当然MVのようにキャプチャしてLoveLiverで切り取ればライブフォトにもできる。無限に遊べる。

9年前のニコマス

さらにアイマストドンのタイムラインをみていると,どうやらブルーバックにできるらしく,スクショを経由して,アイドルだけを切り抜いた透過画像を作れるとのこと。これはもしや・・・昔のニコマスの・・・とiMacのディスクをSpotlightし,かつて作った透過プレイヤーのスクショとコードを発見した。

どうやら遅くとも2008年7月ごろのニコマスにはブルー(グリーン)バック素材の動画があったようで,私はいまはなき(なくはない?)当時最先端のQuartz Composerで,動画をリアルタイムに透過しながら再生するプレイヤーをつくっていたようだ。シェーダーめいたなにやらで色変換を記述することで,LLVM的ななにかでGPUに合わせてコンパイルされ透過がGPU処理となる,ような触れ込みだったはず。 当時のmacOSAPIではこのQuartz Composerのファイルをあたかも動画ファイルのようにプレイヤーのViewに読み込ませることができた。あとは非矩形のウインドウを描く要領で背景透過ウインドウにすれば,アイドルだけがデスクトップに描画されるという仕組み。(→このプロジェクトをHigh SierraXcode 9でビルドして動かす話は,老人会LT需要があったらやりますよ?)

PhotoStudioPlayer構想

あれから9年経ったいまならもっとすごいことが出来るのではないか。iPhone画面はQuickTime Playerで60fpsでプレビューとキャプチャができる。その経路をフックできれば,iPhoneの画面をリアルタイムに透過するプレイヤーができそう。さらにiPhoneでフォトスタジオのアイドルをフリックすれば,アイドルの向きを変えることもできる。

技術的課題を取り除いて透過プレイヤーを支える技術,の構築にひとまずフォーカスする。明らかな障壁はキャプチャ方法である。

  • QuickTime Playerで録画する → ふつうに実現可能だが,録画ファイルよりはリアルタイム処理したい
  • https://github.com/libimobiledevice/libimobiledevice をつかう → ライトニングの通信を解析した系があったような,と見てみたが,iOS 11では動かせなかった。深入りしない。
  • AirPlayをつかう → 出来そうだが圧縮で不利なのと,調査コストは他に比べて低いと分かりきっているわけでもない
  • iOSScreenCaptureAssistantつかう → QuickTime Playerの録画に使われるプロセス。どこが不可能ポイントかすら分からないのでそれが明らかになるまで調べてもいい。

iOSScreenCaptureAssistantの調査

なぜかふつうにmanがある。

iOSScreenCaptureAssistant is used by the CoreMediaIO Device Abstraction Layer Plug-In that provides audio/video capture from iOS devices using AVFoundation Capture APIs. The process allows multiple applications to simultaneously capture from the same iOS device.

複数プロセスからの同時キャプチャにも配慮した設計らしい。実際にQuickTime Playerを2プロセス起動すると,2画面で同時に(やや遅延に差は出る)同じiPhoneをキャプチャできる。 XPC的な制約があるのかはともかく,機能は期待できる。 このプロセスは /System/Library/LaunchDaemons/com.apple.cmio.iOSScreenCaptureAssistant.plist から起動されるようだ。 f:id:banjun:20171107233412j:plain

manのCoreMediaIOとは

https://developer.apple.com/library/content/samplecode/CoreMediaIO/Introduction/Intro.html

CoreMediaIO DAL (Device Abstraction Layer) とは https://developer.apple.com/library/content/samplecode/CoreMediaIO/Listings/Sources_Extras_CoreMediaIO_DeviceAbstractionLayer_Devices_Sample_PlugIn_CMIO_DP_Sample_PlugIn_cpp.html

なるほどわからないが‥ /System/Library/Frameworks/CoreMediaIO.framework/Versions/A/Resources/iOSScreenCapture.plugin にあるキャプチャプラグインを複数プロセスから触れるように,またはカメラとして認識できるように,ラップするものらしい。pluginバンドルとassistantプロセスのパターンは,CoreMediaIO DALではよくあるパターンのようだ。

OBSの調査

ところで3rd partyアプリである OBS - Free and open source software for live streaming and screen recording https://obsproject.com/mantis/ では,iPhoneのキャプチャとクロマキー合成が可能であるとみつける。iPhoneがソースに選べるとは知らなかったが,CoreMediaIO DALになっている仕組みからいって,3rd partyから読む手段はあるのではないか?と機能を探していて,まさにそのものがみつかった。

f:id:banjun:20171107234612j:plain

やりたいことのほとんどは,これで出来ている。画像の上にリアルタイムクロマキー透過したiPhoneを重ねている。あとはウインドウに切り出せれば。 ありがたいことにOBSのソースコードgithubで公開されている。CoreMediaIO関連のコードをいくつか試していたので,見当をつけてgrepすると,iPhoneをソースとして検索するには,前段階である設定が必要であるとわかる。

https://github.com/jp9000/obs-studio/blob/d13fa96851f2f3d0e242b01e164ab5e78af0a30c/plugins/mac-avcapture/av-capture.mm#L2182-L2192

さらにありがたいことに,この情報がWWDCで出ていたこともrefしてある。OBSはGPLだが,この行については完全にWWDCセッションのコピペなので,GPLにこだわらずもらってくる。 AppleWWDCでこの情報を出したとき,私はWWDC現地にいたのだが,「Camera Capture: Manual Controls」というタイトルでこの話を出すのは初見回避というかなんというか。完全にウォッチ対象外であった。

developer.apple.com

(5:34 -)

Swift最小実装化

ともかくこれをpure Swiftで実装しなおして動くのを確認した。

これでAVCaptureDeviceまで来ているので,iOSアプリ勢にもおなじみのポイントまで辿り着いた。 おそらく最も簡単に低負荷再生するにはAVCaptureVideoPreviewLayerであろうということで,そこに置いて,クロマキーなしのキャプチャ表示が実現した。まるでQuickTime Playerである。

f:id:banjun:20171107233938j:plain

クロマキー透過

AVCaptureVideoPreviewLayerのまま軽量な変換ができるとは限らない。これは軽量だが通常のCALayerではない。もちろんキャプチャセッションからサンプルバッファーをもらって画素のメモリを見てしまえばなんらかは変換可能だろうが,できればコードから直接メモリをみたりしたくない。そのあたりは裏でGPUをつかってよろしくやってくれる期待感をこめた実装にしたい。

CoreImageのCIFilterを使ってみる。Appleがオススメするクロマキーの例は,CIColorCubeという色変換のLook Up Tableのフィルタを使うことらしい。

Subclassing CIFilter: Recipes for Custom Effects

ただしそのままではlayerにCIFilterは当たらない‥と思っていたがどうやら,親ビューのlayerUsesCoreImageFiltersをtrueにすれば適用されるようになる。

view.layerUsesCoreImageFilters = true
previewLayer.filters = [ChromaKeyFilter.filter()]

これで,昔のように,ウインドウの背景色をclearにしてnon-opaqueにして,アイドルのみが描画される透過プレイヤーが完成した。

PhotoStudioPlayerアプリ・コード公開

iPhoneMacがあればビルドせずすぐ使えるようにアプリを公開するのと,アプリはともかくこの一連の技術を使ってさらに別のものを作れるようにするのと,という観点で,githubに公開・リリースしてtwitterに貼った。

ばんじゅん🍓 on Twitter: "デレステフォトスタジオがブルーバック対応なので,iPhoneの画面をキャプチャしつつクロマキーして透過再生するプレイヤーをつくった。意外にも公開されている情報だけでつくれた。アプリとソースコードはgithub https://t.co/h1zn5MXdSr https://t.co/l24Xgq2oyJ"

PhotoStudioPlayer公開その後

透過した状態の静止画キャプチャ保存もあったら便利ではあると思って,機能追加した。その話はまた。

@mzp のPull Requestによって,ウインドウの常時前面表示と,複数デバイスのキャプチャ対応(切り替え,ではなく同時表示も可能)に対応した。

iPhone + Mac + デレステ,という組み合わせ以外のプラットフォームにも適用したいという動きがあるようで,いくつか既に実装されていた。 Windows:

Android:

なんとなく,手前のブルーバックiPhone + 奥のデスクトップ画面 + 卯月,という文法で動画投稿されているのが,おもしろい。

GitHub Trending Swift Developer

かつてないほどtwitterからgithubにページビューが流れたなと思い,ふとGitHubのトレンディングのページをみると,Trending Swift Developerの23位に入っていた。repoの⭐️は48になった。

アイマスハッカソン

このあたりの話を含めて,技術はもちろん,よりアイマスに寄った方向性の話も,もっとしたいと思います。 今年の冬のアイマスハッカソンは12月16日(土)とのことなので,是非そこで会いましょう。おはなししましょう。

おわりに

結局iPhone X買えたので,iPhone Xデレステフォトスタジオがクラッシュしなくなると,うれしいです。

2016年振り返り

f:id:banjun:20161230000558p:plain:w261

GitHub(などなど)で振り返る2016年

1月

HanekeへのPRがマージされた https://github.com/Haneke/HanekeSwift/pull/270

2月

movファイルからLive Photoを生成するLoveLiverにGUIをつけた - ツバメになったバリスタ https://github.com/mzp/LoveLiver/pull/3

3月

Swift静的解析試したかった https://github.com/banjun/bansan

関連Qiita: http://qiita.com/banjun/items/3f22b4951bca07cc55c7

Swiftらしく鳥類の名前をつけたライブラリをつくった https://github.com/banjun/Toki

LoveLiverのLive Photo切り出し専用UIをつくった - ツバメになったバリスタ

4月

RSDayFlowにPRするも別経路で解決となった https://github.com/ruslanskorb/RSDayFlow/pull/103

RSDayFlowにPRするもworkaroundを提案された https://github.com/ruslanskorb/RSDayFlow/pull/104

5月

合宿でありす判別学習アプリをつくった https://github.com/banjun/arisu-in-fact mzp.hatenablog.com

RSDayFlowにPRするも別経路で解決となった again https://github.com/ruslanskorb/RSDayFlow/issues/107

6月

WWDCに最小クラッシュ例を持っていき,Swiftバグレポの上げかたを教えてもらった https://bugs.swift.org/browse/SR-1813

その後,Swiftラボで対応してくれた人が直してくれた https://github.com/apple/swift/pull/3093

もうひとつあったので自分で上げた https://bugs.swift.org/browse/SR-1939

7月

SVProgressHUDにPRするも,あまりイケてない別解で対応された https://github.com/SVProgressHUD/SVProgressHUD/pull/646

8月

FlickSKKがiOS 10b5から重くなったので回避した https://github.com/codefirst/FlickSKK/issues/152

9月

FlickSKK 1.4.3 App Storeリリースした https://github.com/codefirst/FlickSKK/releases/tag/1.4.3-3

スタージュエル tumblr をはじめた http://⭐💎.tumblr.com

デレステ SKK辞書,が製作されるのを応援していた https://github.com/mlny/skk-dict-imascgss

10月

とくになく,Xcode 8対応とかしていたらしい。まぁ忙しい月なので。。

11月

Eurekaのレアなバグを調査したのでPRしてマージされた https://github.com/xmartlabs/Eureka/pull/786

Eurekaで,振り返ってみると,ライブラリはSwift 2.3飛ばしてSwift 3が正解だなぁ,というような話をしていた https://github.com/xmartlabs/Eureka/issues/687

WSDL2ObjCというロストテクノロジーをメンテしたくないのでSwift版をフルスクラッチでつくった https://github.com/banjun/WSDL2Swift

Touch Barで卯月をつんつんした

12月

FlickSKK 1.5.0 App Storeリリースした https://github.com/codefirst/FlickSKK/releases/tag/1.5.0-2

デレマス曲名がついたライブラリをつくった https://github.com/banjun/JetToTheFuture

アイマスハッカソンで無限LivePhotoをつくった https://github.com/banjun/LivePhotoShow

GitHub上でコミットする仕事(アイマスP的には副業)だけしていたらめずらしく12 days streaksになった

f:id:banjun:20161229212012p:plain

WWDC

WWDC 2016に行ってきた。 WWDCWWDCラボの話は別途上げたほうがいいですね(とずっと思っている)。 シリコンバレー企業観光よかった。ここでは簡単にまとめだけ。

ラボの成果(見込み含む)

ATS必須化について

LAN(主にオンプレミス)での対策を聞いた。 結果,AppleのATSポリシー自体(どこをスコープとするか)が変更されることとなる。 「アプリによるHTTP通信」ではなく「インターネットに対して行なわれるHTTP通信」をスコープとするようにドキュメントが書き直される。 さらに,謎のATS必須化の期限不明延期がなされる(不穏)。

Live Photoについて

LoveLiverの手法が技術的に正しいことを確認。 https://github.com/mzp/LoveLiver

iOS 10正式版では60fps Live Photoのクラッシュが修正される。 iOS 10.2ではAppleカメラで生成されるLive Photoのfpsが上がる。 ラボエンジニアとの話の内容はアイマスハッカソンLT発表資料を参照

カスタムキーボードについて

外部キーボード対応(iPad Proのとか)はまだうまくいかない感じ。 マーカー(疑似でないインラインモード)もまだな感じ。 「いまはプライベートAPIで実現しているこのTaptic Engineフィードバック感がほしい」というものは,iPhone 7で実現された。(新ハードウェア固有の話だったので,6月時点ではすっきりした回答が得られなかったのだろう)

Swift 3のコンパイラクラッシュについて

あげたバグレポぶんのSwift 3コンパイラは修正されている。上記GitHubの6月参照。 XcodeをつかってSwiftコンパイラデバッグするやりかたと,一次解析するところまでを,Swiftラボのエンジニアにやってみせてもらった。

Apple Developer Program(個人)によるチーム開発について

githubとかでアプリを共同開発するのはつらいよね,という話。Appleはまだ意識が低い。継続的に要望を出していかないといけない。

アイマスハッカソン

imas.connpass.com

LoveLiverの話をどこかでしたいが,アイマスPに届くようなところはあるのだろうか‥?というところでいいイベントを見つけてしまった。 ハッカソンもLTも初めてだったが,楽しくLTできて大変よかった。そして初めてニコ生に出た。 Slackも用意されてやりやすいし,今後につなげていきたい。

LoveLiverについては同日にNGK2016BでmzpがLTしていた。 そもそもLive Photoでなにをしたらいいのか?APIは解析しうるのか?という背景からやがて繋がるデレステ縦MVの話がある。

mzp.hatenablog.com

2016年参加したイベント・行ったところなど

東京に引越してからちょうど1年が経った。 いろんなイベントごとには本当に行きやすくなり,実際にもたくさん行けてよかった。 職場もかわり,OSS的な活動もしやすくなった。 2017年も継続していきたい。やや加速できるとなお良い。

LoveLiverのLive Photo切り出し専用UIをつくった

3月に更新するつもりだったが月末に東京ドームでラブライブ!をみていたので遅くなった。

banjun.hatenablog.com

前回の残された課題のうち,いくつかを完了させ,LoveLiver 1.2.0 としてリリースした。

  • [ ] 3秒以外の長さを指定する
  • [x] 切り出しをプレビューする
  • [x] UIをなんとかする
  • [x] Sketchを体験版から正式版にする(31日以内)

出来上がりイメージ

vimeo.com

LoveLiver 1.2.0のダウンロードはこちら
Release Dedicated UI for Live Photos Trimming · mzp/LoveLiver · GitHub

今回のUIによって狙い通りのLive Photoを次々生成できるようになり,Photos.appにLive Photoがたくさん登録されるようになった。 せっかくなので作成したUIについて解説したい。

動画のOverview

f:id:banjun:20160419004030j:plain

開いた動画のプレイヤーの下に,サムネイル付きシークバー(MovieOverviewControl)を新規に作って置いた。動画の各位置の絵がなんとなく分かるコントロールなので,Overviewと呼んでいる。下記のような動機からつくった。

  • AVPlayerViewの標準コントローラではシークにその他の操作に限界があるので,独自のコントローラビューが必要
  • 主にデレステの縦MVをコンテンツとして使っているので,動画ウインドウ自体が縦長でも,それより横長のシークバーを出したい
  • QuickTime PlayerのTrimはわりとかっこいい(あとiOSの写真の動画再生とか)

プレイヤーウインドウの移動についてくるために親子のウインドウにしたが,リサイズあたりは少し不思議な動きをするかもしれない。

Live Photo切り出しフロー

動画から(3秒の)切り出しを指定するUIはいくつか考えられるが(前回バージョンもそのひとつではある),ここでは 「ベストショットのフレームを指定する」 を第一に考えることにした。

まずはAVPlayerViewでベストショットのフレームをシークして探す。その位置で止めて, Live Photo With This Frame ボタンを押す。 するとそのフレームをポスターフレームとするLive Photoの作成用のPopoverが表示されるので,そこで切り出し位置を調整してPhotos.appに書き出す,というフローになる。

Live Photo切り出しPopover

ポスターフレームを決めると,Live Photo生成用のPopoverが表示される。これをSandboxと呼んでいる。 Live Photoは標準で3秒なので,ポスターフレームを決めた場合,デフォルトでは前後1.5秒をLive Photoの動画部分とする。

f:id:banjun:20160419004110j:plain

実際の動画には,カメラ・シーン切り替え等があり,切り出し位置を調整したいことがよくある。 そこで,さらに前後1.5秒まで,切り出し位置をスライドできるようにする。スライド位置によって切り出される動画は変わるが,最初に選んだベストショットであるポスターフレームは必ず含まれる。

ここでもシークバーとして作ったOverviewを再利用することができる。さらにスコープを設けて,選択されている3秒間を明るく表示する。明るい部分を左右にスライドして調整する操作になる。 動画の最初や最後に,意図しないシーンチェンジ前後のフレームが入っているか確認しやすいように,最初と最後のフレームは最下段に別に表示している。 最上段をクリックすることで,調整後の切り出しでのLive Photo再生をプレビューできる。

不要になったもの

メインウインドウでの動画プレイヤー + ポスターフレームの2枚表示UI

今回のUIフローでは最初の画面は動画プレイヤーのみでよくなり,すっきりした。

Command Line Interface

GUIが便利すぎるので,Swift 2.2対応するときにフェードアウトした。 GUICLIの上位互換ではないが,コアのJPEG.swiftとQuickTimeMov.swiftがあるので,必要なら細かいこともできるはず。

UIこぼれ話

  • 動画ファイルの全体から1点を決める
  • → 周辺6秒が拡大表示され,そのなかから3秒をどこにするか決める
  • → 切り取られた3秒がPhotos.appに読み込まれ,iPhoneで再生できる

というフローは,全体からみえる一点,その拡大,という一方向のズーミングなインターフェースになっている。 もし先に切り出し開始・終了位置を決めるフローになると,そうではなくなる。 ズーミング感を出すために,Popoverの吹き出し位置はポスターフレームの位置に合わせている。

f:id:banjun:20160419004131j:plain

せっかくiPad ProとApple Pencilがあるので,今回はメモアプリで絵を描いてから作ってみた。

おわりに

LoveLiverを使えば動画からすぐにLive Photoを作成できるので,ロック画面を1枚絵だけではなくLive Photoにして楽しんでほしい。卯月はピンクなので,ローズゴールドのiPhoneのロック画面によく合う。背景も揃うとなお良い。

movファイルからLive Photoを生成するLoveLiverにGUIをつけた

f:id:banjun:20160213202915p:plain
Release OSX GUI Application · mzp/LoveLiver · GitHub

インドアLive Photo業界には mzp/LoveLiver というLive Photo生成ツールがある。

mzp.hatenablog.com

これを使って下記のような手順を踏めば,好きな動画の一部をiPhoneのLive Photo壁紙に設定できて便利。

しかし何度もやっていると,QuickTimeで3秒選んでトリムして保存して,LoveLiverのコマンドライン引数を書いて,というのが意外と手間に感じる。 というわけでOSXアプリケーションにすべく,GUIをつくった。

リリースしたGUIアプリはここの LoveLiver-1.0.0.zip からダウンロードできる。
Release OSX GUI Application · mzp/LoveLiver · GitHub

f:id:banjun:20160213203953j:plain

GUIにより,3秒動画を切り出して保存する必要はなくなり,単に使いたい動画をGUIで開けばよくなった。 Live Photoを生成するには,ポスターフレームを設定し,Live Photoを開始したい位置へシークし, Create Live Photoする。 コマンドライン版と同じようにLive Photo用のJPGとMOVを保存したあとは,Photos.appで自動的に開くようにしたので,Photos.app側でImportを押せばフローが完了するようになっている。

これで日々溜まっていく手持ちの動画のLive Photo化が捗るはずだ。

今後の課題

just worksな感もまだあるので,ざっくりと考えていること:

  • 3秒以外の長さを指定する
  • 切り出しをプレビューする
  • UIをなんとかする
  • Sketchを体験版から正式版にする(31日以内)

開発ネタ・雑感

今回のぶんのPull Requestはこちら。
github.com

  • もともとiOSで開発した NorthLayout※ikemenOSXアプリに適用してみた。
  • デフォルトのMainMenu.xibの編集は,メインウインドウの削除のみ。xibはあまり触りたくないがデフォルトのメニューは殺したくなかった。
  • 動画ファイルごとにウインドウを出すのであれば,NSDocumentControllerに任せてしまうのが早そう。ウインドウを閉じずにアプリを終了したときのResumeで再オープンも自動的に対応する。
  • NSDocumentControllerに登録するDocument Typesについては,Swiftクラス名はモジュールプレフィックスが必要だった。アプリ側ターゲットにいると意識しないが, LoveLiver.MovieDocument とする必要がある。あるいは @objc(MovieDocument) class MovieDocument とかにしてobjcに同名でエクスポートする。
  • 最近はNSWindowControllerとNSViewControllerがある程度いけるので,ドキュメントごとのxibは不要で,NorthLayoutのみでいけた。
  • AVPlayerViewとAVAssetExportSessionのおかげで,再生と切り出しはわりと簡単にできた。
  • キャプチャは requestedTimeToleranceBefore = kCMTimeZero requestedTimeToleranceAfter = kCMTimeZero しないとずれたフレームのキャプチャになる。デフォルトだとダメ。
  • fastlane/gymOSXアプリでも使えた。
  • アプリアイコンはSketchで描いてみた。色はデレステのデフォルトステージ衣装から拾った。操作に慣れたい。

WeakStreaks カンスト

前回のエントリで49週だったweak streaksをカンストしました。

www.instagram.com

githubからは1年分のcontributionsを取得しているのですが,53週目は丸々一週間は無いため,ここだけ日単位で気を使わないと53週連続が取れないというプレッシャーがありました。 しかも,Apple Watchのグランス用WeakStreaksの実装は52週までしか出ないようになっていて,どうやら1年が52週だと思っていたフシがあります。

https://github.com/codefirst/WeakStreaks/blob/e7950117f2f10af61a1198f664ed510b525bce9e/Common/WeekStreaks.swift#L19

縦一列灰色というのが無い状態に。

f:id:banjun:20160131234656p:plain

ともあれweak streaksチャレンジはこれで一段落になります。