2024年4月24日水曜日

INFINITASをWASAPI排他で配信したい場合のコスト低減方法

なんだかんだ言って音ズレが発生してる環境はWASAPI共有モードでプレイしてる事が多い。 でも排他にしたら普通には配信できないじゃん!と諦めてる人もいるっぽい。

そんなわけで、一番手っ取り早いのは

  • 出してきた音をアナログ的に2分配 / 500円
  • 片方を外部スピーカーに突っ込む / お好みで
  • もう片方をPCのラインインに突っ込む / 6~700円
  • OBSでラインインをキャプチャ

これで事足りる。

ただ、コメント読み上げは「音声出力デバイスがブロックされてるから流せない」ので、「別の出力デバイスが必要」。

但し。

例えば表示してるディスプレイがHDMI接続でスピーカー付きなら、それがそもそも「別の出力デバイス」である。 その画面から読み上げが流れれば良いなら読み上げの出力先をそちらに向ければ良し。

ただ、ヘッドホン・イヤホンでプレイしてて、どうしてもゲーム音と読み上げを同系統で聞きたいならミキシングする機器が必要になる。 ここは何か安い方法あるかな…

配信に読み上げが流れて、自分は別に目視するから聞こえなくて良い、のなら先の様に別デバイスがあれば良い。
例えばこういうの。(下記参照)
ただアナログ端子側を結線しないと認識しない可能性はあるので注意。
認識したなら出力デバイスに指定できるしOBSもキャプチャできるので、配信に読み上げを載せるのだけなら事足りる。

2024年4月12日金曜日

ChromeでSNSをウィンドウサイズ固定で別ウィンドウで開きたい

という要望を持ったのだが。
  • --window-position, --window-size などのコマンドラインオプションがまともに作用しない。
  • JavaScript指定して調整する方法があるも、windowの体裁が変になる。
  • プロファイルを別に指定するとオプションが効く風でもあるが、プロファイルが変わるとログインが面倒。
ということで、標準的な手順を断念。新規に起動したらいんじゃね?という事に。 Win32API の CreateProcess で chrome 直撃したらウィンドウが別に開いた。嬉しい。 悲報:CreateProcess の引数に渡す STARTUPINFO 構造体の座標・サイズ情報は有効に作用しない! という訳で、新規に開いたウィンドウを自前で探索して移動してやろう! やり方としてはもっとスマートな方法があるのやもしれんが、一先ずこれで。
  1. その時点で開いているChromeのウィンドウのhWndを記録しておく。
  2. CreateProcessでChromeを--new-windowオプションとURLを指定して開く。
  3. ちょっと待機する。(即時にはウィンドウが開かない)
  4. 再度ウィンドウを探索し、先に記録しておいたものと突合し、合致しないのが居たらそいつがルパン。
  5. 対象ウィンドウをMoveWindowでお好きな位置に。
汎用性を持たせた書き方をしたいんだけどパラメータを設定ファイルに持たせるのが賢いのかな…全指定はきちゃない気がする。 一応これで動くよってサンプルはこんなところ。
#include <iostream>
#include <tchar.h>
#include <windows.h>
#include <list>

const TCHAR CHROME_PATH[] = _T( "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" );

struct TFindData {
	std::list<HWND> chromeWnds;
	bool bFound;
};

bool isChromeWindow( HWND hWnd, DWORD& dwProcessId ) {
	bool bResult = false;
	dwProcessId = 0;
	DWORD dwThreadId = GetWindowThreadProcessId( hWnd, &dwProcessId );

	HANDLE hProcess = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId );
	if ( hProcess ) {
		TCHAR buf[ MAX_PATH ] = {};
		DWORD dwBufLength = MAX_PATH - 1;
		if ( QueryFullProcessImageName( hProcess, 0, buf, &dwBufLength ) ) {
			if ( !lstrcmpi( CHROME_PATH, buf ) ) {
				bResult = true;
			}
		}
		CloseHandle( hProcess );
	}
	return bResult;
}

BOOL CALLBACK EnumChromeWndProc( HWND hWnd, LPARAM lParam ) {
	TFindData* pData = reinterpret_cast< TFindData* >( lParam );

	DWORD dwProcessId = 0;

	if ( isChromeWindow( hWnd, dwProcessId ) ) {
		pData->chromeWnds.push_back( hWnd );
	}
	return TRUE;
}

void MoveChromeWnd( HWND hWnd ) {
	MoveWindow( hWnd, 4380, 0, 740, 1440, TRUE );
}

BOOL CALLBACK MoveNewChromeWnd( HWND hWnd, LPARAM lParam ) {
	TFindData* pData = reinterpret_cast< TFindData* >( lParam );
	DWORD dwProcessId = 0;
	if ( isChromeWindow( hWnd, dwProcessId ) ) {
		for ( std::list<HWND>::iterator it = pData->chromeWnds.begin(); it != pData->chromeWnds.end(); it++ ) {
			if ( *it == hWnd ) {
				return TRUE;
			}
		}
		MoveChromeWnd( hWnd );
		pData->bFound = true;
		return FALSE;
	}
	return TRUE;
}

int _tmain( int argc, TCHAR* argv[] ) {
	setlocale( LC_ALL, "JAPANESE" );

	TFindData data;
	data.bFound = false;
	BOOL bResult = FALSE;

	bResult = EnumWindows( EnumChromeWndProc, reinterpret_cast< LPARAM >( &data ) );

	STARTUPINFO si = {};
	si.cb = sizeof( si );
	PROCESS_INFORMATION pi = {};
	TCHAR OPEN_TWITTER[] = _T( "\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" --new-window \"https://twitter.com/home\" \"https://bsky.app/\"\0\0" );
	bResult = CreateProcess( NULL, OPEN_TWITTER, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
	if ( !bResult ) {
		return 0;
	}
	data.bFound = false;
	for ( int i = 0; i < 5; i++ ) {
		Sleep( 200 );
		bResult = EnumWindows( MoveNewChromeWnd, reinterpret_cast< LPARAM >( &data ) );
		if ( !bResult ) {
			break;
		}
		if ( data.bFound ) {
			break;
		}
		Sleep( 300 );
	}

	CloseHandle( pi.hThread );
	CloseHandle( pi.hProcess );
	return 0;
}

2022年6月26日日曜日

WOL の設定は環境整えてからやろうな

結論:ドライバは最新にしなさい

MeLE Quieter2Q というミニ PC を調達したのですよ。

発売当初は Windows 10 であった模様ですが、今では残念ながら(?) Windows 11 のモデルしか希望の構成がない…ので初 Windows 11 としゃれ込みました。

希望として WOL ( Wake On LAN ) があり、対応しているとの事だったので調達した次第。もうお分かりの通り…

S5 からの WOL が利かない

色んなページを検索してヒットするのですが、全然ダメでした。レジストリまでいじったよ。

この機種、そういう意味では優秀で、基本的な設定はしてあります。

  • BIOS で WOL が ON になっている
  • Realtek 系 NIC でレジストリの S5Wakeup みたいな設定が ON になっている
  • 高速スタートアップの設定がそもそもない

なので殆ど確認をしていく、又は枝葉の設定を追加していったのですが全く改善せず。

Windows 11 用のドライバを入れ直して、基本設定をし直して事なきを得ました。 I got the KOTONAKI.

多分必要設定。

  • ドライバを更新してインストール
  • デバイスのプロパティを開いて詳細設定
    • ウェイク・オン・マジックパケット:有効
    • ウェイク・オン・パターンマッチ:有効
    • WOLとシャットダウンリンク速度:10Mbps
    • グリーンイーサネット:無効
    • 省電力型イーサネット(EEE):無効
  • デバイスのプロパティを開いて電源の管理
    • 全部のチェックを入れる
    • 電力の節約のために、~
    • このデバイスで、コンピューターのスタンバイ状態を~
    • Magic Packet でのみ、コンピューターのスタンバイ状態を~

恐らく利いているのはグリーンイーサネットやら省電力型イーサネット辺りで、何故かと言えばドライバ更新前にあった同設定について Disable に設定しても WOL が正常に動作しなかったのに、ドライバアップデート後にこの設定が有効になっていたから。ちゃんと反映できていないという事じゃなかろうか。

これで magic packet 投げ込めばちゃんと動きます。

なお S5 じゃない状態での WOL はアップデートしなくても動くので、ここらへんまでのチェックしか公式がしてないって事なんじゃないかな。

2022年6月7日火曜日

INFINITAS 環境と状況

結論:これは検証じゃなくて、備忘録的な何か。

確か 2019 年頃から INFINITAS と立ち環境の構築については検討を始めており、新しく TV を買うこと、テーブルを買う段階から INFINITAS 立ち環境を含めた構成にしようとしていました。

TV : TOSHIBA REGZA 65Z730X
https://archived.regza.com/regza/lineup/spec/65z730x.html

65インチ 4K ( 3840x2160 ) で、1920x1080 なら 120Hz も対応している凄い奴だよ!低遅延モードも捗るよ!

その前から Dead by Daylight もやってたけど、でかい画面でド迫力環境でやりたいなぁと常々考えてこの選択を。全く後悔はしていない。丁度後継の 740X が出始めた頃で 730X の限定処分品だった。

なお 1280x720 で拡張表示をやめると丁度 43 インチほどで表示されるので、アーケードに近い感じが出るのではなかろうかと。これ今後の事を考えても買い直すケースでも 65 インチが最適解なんじゃなかろうか。 43 インチ少なくなってるみたいですし。

TV スタンド : MV901
https://sp-direct.jp/products/detail/?product_id=518

当然高さを変えられる術を用意せねばならん!という中で検討して導き出された唯一解。電動のは高すぎるし調整可能幅などを検討した結果、これがベストだと判断。

デメリットは足部分が無骨ででかい位ですが、どうせメタルラックで避けるし隠すし問題はない。

因みにスタンド上部にカメラなどを取り付けられるパーツまで同梱されていたが HA-HA-HA カメラなんて付けるわけないじゃないか、なーんて付けずに組み立てを完了してしまったあの日の自分を殴りたい。手元カメラぇ…

テーブル : ニトリ 昇降デスク(マーフィー2 120 DBR)
https://www.nitori-net.jp/ec/product/6201500s/

TV をパソコンモニターとして使う、すなわち座って使う事と、立ち環境の両立を検討して、それなりの天板サイズ、高さ調整幅、お値段と相談して選びました。お値段 3 万円という秀逸さ。

メリットはそれなりの重量感、頑丈さ、高さ調整の容易さ、そして何より天板サイズのジャストフィット感。天板の手前両隅にプロコンを配置すると中央部に丁度 10cm 程度の隙間ができるという最適設計。

デメリットは、場所は取る事。ただ快適な環境な分だから仕方がないのではなかろうかと!あと組み立ては二人でやろうね!一人はかなりしんどい。


以下進行状況。

  • 2020/2 ~ 4 : TV やら色々購入
  • 2020/11/17 プロコン申込 / 2021 夏を待ちわびる
  • 2021/6 : 待ちきれなくなりつつ INFINITAS の動作検証をトライアル版で keyboard ポチポチしてお茶を濁す
  • 2021/8 : 夏も終わりかける中、「夏の定義とは!?」と騒ぎ出して数日後、無情にも延期のお知らせが告知
  • 2021/10/29 : 専用コントローラもある内に買わないとと、血迷ってポップンコン購入
  • 2021/11/1 : プロコン宛先確認のお知らせに歓喜 / なお同日発送完了通知に「?」も、ポップンコンの方…
  • 2021/11/12 : プロコン発送完了通知
  • 2021/11/13 : INFINITAS コース加入も keyboard プレイ
  • 2021/11/15 : プロコン到着
  • 2021/11/17 : SP 段位認定 七級 ~ 四段
  • 2021/11/20 : SP 段位認定 五段失敗 DP 段位認定 七級 ~ 六段
  • 2022/4/12 : SP 夏の匂い。キミの残像。(H)初フルコンボ
  • 2022/4/23 : SP 段位認定 五段 六段
  • 2022/5/15 : DP 夏の匂い。キミの残像。(H)初フルコンボ
  • 2022/7/12 : DP 段位認定 七段
  • 2022/8/28 : DP 夏の匂い。キミの残像。(A)ノマゲギリクリア
  • 2022/12/4 : AC(RESIDENT) DP 段位認定 三段 ~ 七段
  • 2023/5/17 : DP 段位認定 八段
  • 2023/8/5 : AC(RESIDENT) DP 段位認定 極七段+八段

ここから今のところ動きがなく、地力上げしてくしかないのかなと。指動かなーい。

2022年6月5日日曜日

OBS をバッチファイルで起動するには

結論:カレントディレクトリがそこになってないと失敗するよ!

なお、マルチコメントビューアもです


前述のバッチを、ツールだけ起動する部分だけで検証してたときに OBS 及びマルチコメントビューアが起動しなくて悩む。まずは OBS 。


これは記述のあるサイトがありました。 OBS が居るディレクトリに移動してから起動しましょう。


D:
cd D:\app\obsstudio\bin\64bit
start "" obs64.exe


start コマンドの最初のダブルクォートは起動のためのプロンプトのタイトルです。空で良いのでこんな書き方。

ディレクトリの指定はインストール先です。


OBS は起動されたときに、その時のカレントディレクトリを起点として設定ファイルを読みに行くので、カレントディレクトリがインストール先でない状態で起動すると「適正な設定ファイルを読み込めない」旨を出力してエラーで終了します。

作成してあるショートカットからの起動は当然カレントディレクトリはインストール先で起動するから大丈夫であり、そういう仕組みに気がつかないというお話。


という事でこちらを解消してからマルチコメントビューアが居ないことに気がつきました。

因みにタスクマネージャのプロセス一覧ではちゃんと居ます。画面が非表示です。


マルチコメントビューアも OBS と同様ですが、タチの悪いことに非表示で起動しつつ、カレントディレクトに設定ファイルをまき散らします。

ゴミを消しつつ、こちらも起動方法を改めましょう。


D:
cd D:\app\mcv
start "" MultiCommentViewer.exe

INFINITAS 配信の為の手順の省力化

結論:バッチファイル作りました


手順としましては

  1. サウンドデバイスを TV からオンボード出力に切り替える
  2. 画面解像度を 1280x720 120Hz に切り替える
  3. 棒読みちゃんを起動
  4. マルチコメントビューアを起動
  5. OBS を起動
  6. N Air を起動
  7. N Air で枠を作成 / 作成時の説明をコピー
  8. YouTube で枠を作成 / 上記説明文流用
  9. N Air で枠 url をコピーしてマルチコメントビューアに貼り付けて接続
  10. OBS で録画を開始しつつ YouTube への配信を開始
  11. N Air で配信開始・番組開始


後半はまだまとまらないものの、前半だけでも手作業でやってると案外面倒だった事に気がつきました。


という事でバッチファイルにまとめて一安心。


rem サウンド切り替えます
D:\app\mytool\changesound.exe スピーカー

rem 解像度を切り替えます
D:\app\mytool\to1280.120.full.exe

rem 各種ツールを起動します
D:

cd D:\app\bouyomi
start "" BouyomiChan.exe

cd D:\app\mcv
start "" MultiCommentViewer.exe

cd D:\app\obsstudio\bin\64bit
start "" obs64.exe

timeout /t 8 /nobreak

C:
cd "C:\Program Files\N Air"
start "" "N Air.exe"


後半を省力化するにはどーしたもんだか。

なお、戻すのも面倒なので画面切り替えとサウンドの戻しはバッチファイルにしました。便利便利。

バッチファイルと文字コード

結論:バッチファイルの記述を UTF-8 で日本語混じりで書いたらそら死ぬよね。


先のツールを作って、コマンドラインで実行して正常。

ショートカットを作って起動して正常。

よっしあとはバッチファイルを作って呼び出せば!



と、失敗するわけです。


rem サウンド切り替えます
D:\app\mytool\changesound.exe スピーカー

rem 解像度を切り替えます
D:\app\mytool\to1280.120.full.exe

rem 各種ツールを起動します
... (snip) ...


何が影響しているのか…と思ったら、使ってるテキストエディタの標準文字コードが UTF-8 であり、日本語を使わない限りであれば特段問題がなかったものの、使い始めた瞬間に狂ったと。まぁそういうお話。

久々に凄い盲点でした。一時的に出てるコンソールに凄い文字化けあるよなというところで気付いた。


因みに timeout コマンドが地味に便利です。昔は sleep とかツール作ってる人いたけど。

標準でついたの、偉い。

INFINITASをWASAPI排他で配信したい場合のコスト低減方法

なんだかんだ言って音ズレが発生してる環境はWASAPI共有モードでプレイしてる事が多い。 でも 排他にしたら普通には配信できないじゃん! と諦めてる人もいるっぽい。 そんなわけで、一番手っ取り早いのは 出してきた音をアナログ的に2分配 / 500円 片方を外部...