Youtubeでライブ配信する際にボイチェンと自動字幕を入れてみた
ゲームのライブ配信で色々試してみたい!
ということでボイチェンと音声を解析して字幕をつけてくれるツールを試してみました。
配信環境はスタンダードにOBSです。
そしてボイチェンと字幕をいれた動画がこちら
ボイチェンについてはあまりうまくいってないので今後の課題って感じです。
最初の数分は準備に手間取っているので飛ばしてみてください。
使用ツール
- speech-to-text-webcam-overlay
となります。
恋声は無料で使えるボイチェンツールでリアルタイムに出力できます。それをデスクトップの出力としてOBSが受け取り声を出しています。 そのときにマイクは切っておかないと声を変える前の音も流れるので注意です。
speech-to-text-webcam-overlayに関してはたまたまTwitterで見つけました。
音声認識からWebカメラ映像への字幕合成までをGoogle Chrome だけでやってくれるWebページをつくってみました! #xDiversity
— Ippei Suzuki (@1heisuzuki) May 20, 2020
ブラウザを画面共有 or OBS等でキャプチャーすればビデオ会議に字幕付きで参加できます。
↓Webページhttps://t.co/xlGX4jkIJn pic.twitter.com/Y1ju1wfUvq
そもそもはカメラも使用して動画に字幕を載せるものなのですが今回はページを開いてカメラの許可を与えずマイクの許可だけを与えました。すると真っ暗な画面に文字だけ残るのでそれをOBSの ウィンドウキャプチャ
でうまくトリミングしつつ画面に出しています。
声の音を認識してテキストに起こすわけなので精度はそれなりになります。ただ間違って意味わからないテキストに起こしてくれることもあるので面白いです
↑こんなことは言ってない
ChromeのウインドウをOBSに出力する際の注意点
Chromeの設定にもよりますがもしかするとウインドウキャプチャの画面が真っ暗になるかもしれません。私は真っ暗になっていました。 これを解決するために調べると
という記事を見つけました。これはChromeの設定にある ハードウェア アクセラレーションが使用可能な場合は使用する
という項目をオフにすることで解決ができるという詳細に書いてくれた記事です。
これのおかげで自分は解決して配信することができました。
まとめ
世に出ている様々なツールの組み合わせで色々な配信画面を作ることができるなと思いました。今後もツールを見つけていき面白い配信環境を作ってみようと思います。 Speech to Textに関しては配信に特化したツールとして自前で作るのも面白そうな気がします。特定の文字が来たら色を変えるや、声の音量で文字の大きさが変わるなどちょっと妄想が膨らみます。
追記
ボイチェンについては調整すると結構よくなりました
恋声のEffectとOBSのフィルターを通せば結構いい感じです
スマホゲームの攻略動画をYouTubeにアップしてみようと思ったら環境がなかった
アークナイツハマってるし動画アップしてみるか
最近、アークナイツというゲームにハマっています。
世界観やUIがカッコイイのです!!
タイトル画面はこんな感じでスマホを傾けると動く…これだけでも楽しい…
そしてゲームに詰まったら動画みてプレイの参考にしています。 そこで自分のプレイも誰かの参考になる…かも?と思い遊びがてらアップしてみたいと思いました。
ここでスマホゲームの録画について調べると
って感じでした。
手元の環境では
詰みました。
アップした動画
縛りプレイとかはしてないので素直に全力なパーティーでプレイしています。
普通にキャプチャできるようにみえますよね…? 工夫…というよりシンプルにアナログハックです。
スマホ単体録画を行った
録画自体は
こんな感じでマイクが雑音を拾わないようにヘッドセットのマイクを食いこませてやってました。
録画アプリはこちら
android9までだと外の音を拾います。つまり録画中に物音を立てないようにひっそり動いたりとかめんどくさい気遣いをしています。
素直にキャプチャーボードを買った方が良いなと実感しております。 そのうち買おう…
追記
後日キャプチャーボード買いました
それでキャプチャしたのがこちら
音質が段違いですね、素直にキャプチャーボードを最初から買えばよかったです
つぶやきGLSLに投稿してみた
つぶやきGLSLとは
Twitterの文に納まる文字数で投稿されるGLSLで描かれたものです。最近では つぶやきProcessing などTwitterの文字数に収めて投稿する流れがある気がします。
#つぶやきProcessing - Twitter Search
様々な人が投稿していて参考になる書き方や短くするテクニックが具体的に見れるので結構楽しいハッシュタグです。
つぶやきGLSLを見ていると
というエディターを使って書いてる人が多いようでした、このエディター自体はGitHubに公開されていて興味のある人は中身を全部把握できるようになっているようです。
エディターを見つけてやってみるかーと思いやってみました
投稿した内容
void main(){float a=smoothstep(.2,.8,mod(t,1.)),s=floor(mod(t,3.)),q=mix(0.,360.,sin(t))*.01;vec2 p=(gl_FragCoord.xy*2.-r)/r.y;p=mat2(cos(q),-sin(q),sin(q),cos(q))*p;p.xy=abs(p)/abs(dot(p,p))-vec2(cos(t)*.4);gl_FragColor=mix(p.yxx,p.yyx,step(180., q)).xyyy;}#つぶやきGLSL pic.twitter.com/GOXiL3vXTi
— あるど (@OrangeGKeeper) April 26, 2020
上記のツイートが投稿したものでGLSLをあまり深く触ってなかったのもあり雰囲気で書いていました。書いた感想としては
- 140文字に収めるのは大変
- 変数名はとにかく省略
- 実際に動くものができると省略していくのが楽しい
って感じでした。
書いたときの環境とコード
投稿すると…
投稿してから、のたぐすさんからリプが来ました(別途省略したのを教えてもらっていましたが最終結果をリプで教えてもらいました)
void main(){vec2 p=abs(mat2(cos(sin(t)*4.+vec4(0,8,5,0)))*(gl_FragCoord.xy*2.-r)/r.y);gl_FragColor=p.yxxx/dot(p,p);}
— notargs (@notargs) April 27, 2020
このあたりが限界っぽそう
自分が投稿した文の半分くらいで同じ動作ができるコードが書けることに結構感動しましたw
半分省略できるということは、もっと表現を加えれるのでMorphingを付け加えてもいいなと考えたりしてます。
まとめ
つぶやきGLSLはかなりお手軽に投稿できますし、気分転換とかにやっていこうかなと…
リプをくれていた、のたぐすさんが最近記事を公開しており notargs.hateblo.jp
中身をみるとかなり参考になるtipsばかりでした!
GLSL自体見るの楽しいので
などを眺めつつやろうかと
追記
後日改良してみたりしました
void main(){float a=mix(0.,1.,mod(t,1.)),s=floor(mod(t,3.));vec2 p=(gl_FragCoord.xy*2.-r)/r.y,k=p/2.,i=vec2(0,1),f=vec2(dot(p,p),1),d=mix(mix(mix(k,f,a),mix(f,i,a),s),mix(i,k,a),step(2.,s)),c=abs(mat2(cos(sin(t)*4.+vec4(0,8,5,0)))*p);o=mix(c.yx,c.xy,step(d.y,d.x)).xyyy/dot(c,c);} pic.twitter.com/nrdHHqrxwZ
— あるど (@OrangeGKeeper) May 3, 2020
箱庭の音
音を基軸としたコンテンツを作ってみたかった
たまにMVとかを自動化できたら面白そうかなとか思っていたので形にするならどうなるんだろう?と思って作りました
音によって色々なパラメーターが変わるコンテンツです
※音が出ます
音に合わせてカメラが揺れたり、傘の移動速度が変わったりします。
さらに音を好きな音楽に変えることができてwavファイルのドラッグ&ドロップで放り込めば切り替わって、切り替えた音を取得して動きが変わるコンテンツになります
音によって空間の動きが変わるけど一部しか観れないので箱庭っぽいなぁということで「箱庭の音」というタイトルにしています(多少キャッチーなタイトルがよかったかも)
影しか写らない横断歩道は自分の世界観なだけなので特に理由がないです
開発環境など
コアとなる部分はUnityで作っていてドラッグ処理などをVue.jsで繋げています
有料Assetsも使ってるのでリポジトリを公開しているもののUnityプロジェクトは誰でも触れるものにはなってないです。。。
Vue.jsから11MBのファイルをUnityに渡すためにbase64するとメモリが足りなくなったりと意外と気を遣うところが出てきたりしました。。。
あとはVue.jsをまともに触るのは初めてだったので作りがかなりイケてないんだろうなと思ってますが作りきることのが大事だと思ってるのでとりあえず作りました(cssが相対的でなかったりビルド後のファイルパスを相対的に治したり…設定があるんだろうけど動かしたかった)
wavファイルを動的ロードする際にUnityWavというのを使ったのですがバイナリの読み取りに柔軟性がなくforkして修正するなどしてました → forkしたリポジトリ
そしてAudioの数値取得は
AudioSource-GetSpectrumData - Unity スクリプトリファレンス
で通常はできるのですがWebGLだと動かないため
を使って実装しました、、、動いてよかった
ホントはSoundCloudのapiを叩いて自由度もあげたかったけどノウハウなさすぎたので一旦断念中
実は昔のプロジェクトをベースとしている
UnityをVueで動かすノウハウ Unityで吐いたWebGLをPWAで動かしてみた - Qiita
遊んでただけの音からパラメーター取るロジックや
ちゃんと修復するところから速攻壊れるところまで撮影できた#unity3d #madewithunity pic.twitter.com/UzDvtk4DiF
— あるど (@OrangeGKeeper) April 4, 2018
見た目に凝ろうとして途中断念したプロジェクトを掛け合わせて作りました
バグで荒ぶる豆腐と影だけの傘 pic.twitter.com/01QjYmWsIM
— あるど (@OrangeGKeeper) March 12, 2019
そのため二週間くらいで作りきれたので蓄積大事だなと思っています
さいごに
今後「箱庭」の種類を増やして音を分析して自動的に見た目を変えたりしていきたいと思っています
そのために
を使ってもっと取得できるパラメーターを増やして遊べるとよさそうだなぁと思ったり
動画とはちょっと違うところがありますが動画としてみれるようにpinp(ピクチャーインピクチャ)機能を使う表示も視野にいれてみたい…
Unity2019.3からのXcodeプロジェクトでSwiftが使えるのか検証
obj-cを書きたくない
シンプルにそれだけ
僕はSwiftが使いたい
そして来たるUnity2019.3…Unityのコア部分が.frameworkになるらしい
まぁそれだけなら気にしないしBuildのPostProcessを変えるくらいだろうと思ったら
下のコメントに
However for iOS, we won’t be supporting SWIFT for now, our focus in on Objective C.
Swiftのサポートは考えてない…?
え、まじで
まずは動かす環境を整える
2019.3.5f1を検証に選びリポジトリは以前
Unityのネイティブプラグイン(macOS/iOS/tvOS)のソースコードを共通化する - 勉強不足で至らんブログ
で使用した
GitHub - MizoTake/ApplePlatformNativePluginSample
を使うことに
検証のためにリポジトリにあるPostProcessは全部コメントアウトした
動かそう
UnityビルドしてXcodeでビルドするが案の定エラー
エラーが出てきて解決していくが
"Umbrella header not found"
というのだけ解決ができなくて悩んだ
ただネイティブの記事で
というのがありネイティブで可能ならUnityもできるはずと思い調べる
https://forum.unity.com/threads/build-ios-umbrella-error.838879/
Which states that it is a regression bug and is not happening in 2020.1 beta.
まじかよ
ということで2020.1をインストール
動くやんけ
しかもSwiftのバージョン勝手に設定してくれる様になってるやんけ
最高かよ
まとめ
2020ベータなら動いたので2019.3でSwiftのネイティブプラグインを使うのは避けた方が良さそう
これからもSwiftネイティブプラグインは使用可能!
ScreenBrightnessRangeSettingを公開しました
Androidネイティブを作ってみたかった
興味本位と勢いで作ってリリースしました
とてもとても業務レベルには至らないと自分で思いつつ開発していました
スマホの画面輝度の自動調整を範囲制限できるものになります
iOSでできなさそうなものを考えて作ってみました
ソースコード自体は全部公開してますが設計思想も何もないです
初めてのAndroidネイティブアプリでKotlin要素のみという経験でした
バックグラウンドで動かすあたりがとても怪しく勢いです
一番知見だったのは、Google Playストアでもきちんと審査されるようになっているんだな…と…昔は数時間でリリースできたのに今回は4日前後かかった気がします
今後は暇作ってUIとかアプリ名とかぼちぼち更新していこうかなと…
StateMachineBehaviourにInjectする
StateMachineBehaviourにInjectする方法
ZenjectでStateMachineBehaviourを使ってみたいと思ったのが発端で
Zenject/ReleaseNotes.md at master · modesttree/Zenject https://t.co/XoVFTuFTgZ
— あるど (@OrangeGKeeper) 2020年3月4日
> Fixed to automatically inject StateMachineBehaviour derived classes attached to Animator components
😎
検索すると自動的にInjectできるようになったそう…だがMonoBehaviourと同じように[Inject]を付けても実行されない…
調べると
Zenject/ZenjectStateMachineBehaviourAutoInjecter.cs at master · modesttree/Zenject https://t.co/WitRiVG6iV
— あるど (@OrangeGKeeper) 2020年3月5日
naruhodo
ZenjectStateMachineBehaviourAutoInjecter
というのがある
中身をみるとシンプルで
using ModestTree; using UnityEngine; namespace Zenject { public class ZenjectStateMachineBehaviourAutoInjecter : MonoBehaviour { DiContainer _container; Animator _animator; [Inject] public void Construct(DiContainer container) { _container = container; _animator = GetComponent<Animator>(); Assert.IsNotNull(_animator); } // The unity docs (https://unity3d.com/learn/tutorials/modules/beginner/5-pre-order-beta/state-machine-behaviours) // mention that StateMachineBehaviour's should only be retrieved in the Start method // which is why we do it here public void Start() { // Animator can be null when users create GameObjects directly so in that case // Just don't bother attempting to inject the behaviour classes if (_animator != null) { var behaviours = _animator.GetBehaviours<StateMachineBehaviour>(); if (behaviours != null) { foreach (var behaviour in behaviours) { _container.Inject(behaviour); } } } } } }
となっており手動でComponent追加すればStateMachineBehaviourにInjectする感じぽい
ただ前提として 最初からSceneにあること
なので動的にやるとき用に少しだけ変えて
using UnityEngine; using Zenject; namespace Hoge.Components { public class StateMachineBehaviourInjector : MonoBehaviour { public void InjectionTo(Animator animator) { var behaviours = animator.GetBehaviours<UnityEngine.StateMachineBehaviour>(); if (behaviours == null) return; foreach (var behaviour in behaviours) { // DiContainerがProjectContextでいい場合 ProjectContext.Instance.Container.Inject(behaviour); } } } }
って感じで外から呼べるようにして使うようにした
ちゃんとInjectされたのでめでたしメモ