どうもこんにちは
Dreamin'Her -僕は、彼女の夢を見る。- 攻略しました。(全年齢)
声優さんが良かったです(詳しくないので分からないですが)
中盤がけっこう?重いのですがエンディングはよく出来てていいと思います。
タイトル通りだ...
あとOP曲がめっちゃいい。
作品とリンクしてる!!!
せめて 私を 過去にして 今紡ごう 未来を ...
OP曲のおやすみモノクローム
、めっちゃいい
(ゲームはSteamで買えます。)
本題
最近のブラウザって数行かけば画面の録画が出来るらしいんですよね、試してみます。
前回の記事の副産物になります これ
ブラウザで録画するまで
getDisplayMedia
で画面録画のMediaStream
を取得
- ↑
MediaRecorder
の入力にする
webm
が出来る
なんやこれ...Androidでやるより簡単! ( https://takusan23.github.io/Bibouroku/2020/04/06/MediaProjection/ )、JSすげ~
流石にPC版にしか実装されてませんでしたが、そりゃそうか→ https://caniuse.com/?search=getDisplayMedia
環境
なまえ | あたい |
---|
Windows | 10 Pro 21H2 (Win11のコンテキストメニュー使いにくいのどうにかならないの;;) |
Chrome | 105 |
多分localhost
みたいな内部サーバーを立てなくても、file
スキーマで動く...?
ブラウザでパソコンの画面を取得する(ミラーリング)
<video>
でパソコンの画面をミラーするだけならこれだけで動きます、何やこれ一体...
これだけ(Promiseがリジェクトされた場合などは見てないですが)でパソコンの画面がvideo要素内で再生できています!
パソコンの画面を録画する
MediaRecorder
にgetDisplayMedia()
の返り値を入れることで、録画もできます!
参考になりました!
https://qiita.com/miyataku/items/6ed855a7fb7507ccc244
ちゃんとダウンロードできる
ちなみにこれで生成されるwebm
は再生時間がヘッダー部分に入っていないため、シークが遅いらしい。
ここまでのソースコードおいておきます
https://github.com/takusan23/browser-screen-record
index.html
をコピペしてブラウザで開けば使えると思います。
しくみ
MediaRecorder
のondataavailable
は録画したデータが貰えるコールバックになってます。
MediaRecorder#start()
の引数に時間をミリ秒で入れると(上記だと100ミリ秒(0.1秒))、その時間の間隔でondataavailable
が呼ばれます。
これを配列に順次保存して、最後に結合してダウンロードしています。
つまり、ondataavailable
で貰えるデータを他のブラウザとかに何らかの方法(WebSocket
とか)で送信できれば、ローカルライブ配信の完成になります。!!!
ちなみに、ondataavailable
はあくまでもデータを分割してるだけなので、全部揃わないと動画ファイルとしては成り立たないです。
最初の動画は単独で再生できますが、2個目以降はメタデータ?が入ってないので再生できません。
(もしかすると最初のヘッダー部分があればなんか再生できるかもしれないです...)
これができれば WebM でライブ配信が出来るのでは?
前回の記事 のAndroidと違い、サーバー側が必要ですが似たようなことができそうなのでやってみます。
環境
なまえ | あたい |
---|
サーバー側言語 | Kotlin (Ktor使いたい...!) |
サーバー側技術 | Ktor |
フロント側技術 | dash.js |
WebM / MPEG-DASH でライブ配信
MPEG-DASH
で出来るのですが、ただWebM
を公開すればいいというわけではなく、初期化セグメント
とメディアセグメント
に分ける必要があります。
が、今回は面倒なので最初に出てきたwebm
を初期化セグメントとして使おうかなと
ちなみに初期化セグメント
は多分Clusterの開始タグ
(0x1F 0x43 0xB6 0x75
)の前までです。ちゃんとやるならその範囲だけのファイル(init.webm
)みたいなのを作るべきだと思います。
詳しくは 前回の記事 で
ちなみ に最初に出てきたwebm
を初期化セグメントとして利用できる理由
単純にClusterの開始タグ
より前の部分が含まれているから。
デコーダーの起動に必要なメタデータが含まれているのが、最初に呼ばれるondataavailable
にはある。
(2個目以降には含まれていないため、2個目以降のバイナリを渡したところで再生できない;;)
Ktorで適当にAPIをつくる
バックエンドは何も詳しくないので...
/api/upload
- Webフロントの
MediaRecorder
のondataavailable
が呼ばれたらバイナリを送るAPI。POST
- よく知らんけど
multipart-formdata
にする
/
index.html
を返す、視聴ページ 兼 録画ページ
manifest.mpd
MPEG-DASH
のマニフェストを返します。dash.js
に渡す
segment1.webm
、segment2.webm
...
/api/upload
のファイルを保存しているフォルダを静的配信する
- Ktorのstatic公開機能で
サクサクっと作る
適当にIDEA
でプロジェクトを作ります。
Ktor
、簡単にWebサーバーが立てれていい感じ。バックエンドよく分からんけど;;
ライブラリを入れる
build.gradle.kts
に書き足します。
Main.kt
なんかMain.kt
がドメインのパッケージに居ない(と言うかドメインのパッケージすら無い)ので作って移動させます。
Kotlin
だといらないんですかね(そんな事ある?)
ドメイン名.アプリ名
みたいな感じのパッケージを作って移動させました。io.github.takusan23.browserdashmirroring
フロントが投げてきたデータは上記の例だとここに保存されます。
index.html
resources
に置きます。こ↑こ↓です
manifest.mpd
これもresources
に置きます。
とりあえず動いたのを書いてるので、多分なんか無駄なことしてると思います。
起動
main関数
の再生ボタンみたいなのを押すと起動できます。
▶ ←これ
http://localhost:8080
を開き、配信開始
を押します。配信でもプレビューが流れます。
数秒後にもう一つブラウザでhttp://localhost:8080
を開き、今度は視聴開始
を押します。これで配信側の映像が流れてくると思います。
スマホでも視聴なら出来るはず。
すごい!!サーバー側は仲介しかして無いのになんちゃってライブ配信が完成しました!
真面目に作るには
動いたことに満足したのですが、まだ直したほうがいいところがあります。
- 配信をやめて再配信する場合
- 再度配信するためにはセグメントフォルダの中身を消すのと、インデックスを0に戻す必要があります。
- 現状はサーバーを再起動しないと再配信できません。
- 視聴側が最初から再生されてしまう(すでにセグメントが生成されているのに)
- リロードして視聴を再度始めると最初から始まる
- $Number$ を
0
から開始しないようにすればいい
- マニフェストで
availabilityStartTime
をセットすることで、途中から視聴した場合も最新のが取得されるはずです。
availabilityStartTime
はライブ配信が利用可能になる時間(ISO 8601)
availabilityStartTime="2022-09-13T00:00:00+09:00"
Q&A
iOS と iPad OS で再生できますか
- iPad OS なら再生できると思います
- iOS は
MediaSource Extensions API
に対応すれば動くと思います。
詳しくは 前回の記事 で
参考になりました
助かります!!!
おわりに
お疲れ様でした、ノシ 888888
ソースコードです
https://github.com/takusan23/BrowserDashMirroring