YouTubeを一緒に見る

モデレーター以上が選んだYouTube動画を、チャットルームの全員で一緒に見るサンプルです。

最終更新 2026年10月19日

このページ

モデレーター以上がYouTubeのURLを入力すると、チャットルームの全員に同じ動画が表示されます。動画IDをチャンネルで送って保存しておくので、あとから入室した人にもいまの動画が表示されます。

コード

次のコードをそのままページに入れれば動作します。最初の行は、uchat.js が読み込まれる前にイベントを登録しておくための事前登録コードです(非同期読み込みと複数のチャットルーム)。

<script>U=window.U=window.U||{},U.events=U.events||[],U.chat=function(n){return{on:function(e,t){U.events.push([n,e,t])},off:function(e){for(var t=U.events.length;t>0;)U.events[--t][0]==n&&U.events[t][1]==e&&U.events.splice(t,1)}}};</script>
<script async src="https://client.uchat.io/uchat.js"></script>
<u-chat room="my-room" style="display:inline-block;width:100%;max-width:400px;height:500px"></u-chat>

<script>
U.chat('my-room').on('after.create#youtube-demo', function (room) {
	var ui = room.skin;
	var channel = room.plugin.add('youtube-demo');
	var removeOverlay = null;

	function show(id) {
		if (removeOverlay) removeOverlay();
		removeOverlay = null;
		if (!id) return;
		removeOverlay = ui.mount.overlay({
			id: 'youtube-demo.player',
			layer: 'content-overlay',
			scope: 'message-list',
			mount: function (host) {
				host.style.pointerEvents = 'none'; // 空いている部分は下の会話をクリックできるように
				var frame = host.ownerDocument.createElement('iframe');
				frame.src = 'https://www.youtube-nocookie.com/embed/' + id + '?autoplay=1';
				frame.allow = 'autoplay; encrypted-media';
				frame.style.cssText =
					'position:absolute;top:8px;right:8px;width:320px;height:180px;border:0;pointer-events:auto';
				host.appendChild(frame);
				return function () {
					frame.remove();
				};
			},
		});
	}

	function videoId(text) {
		var m =
			/(?:youtu\.be\/|v=|embed\/|shorts\/)([A-Za-z0-9_-]{11})/.exec(text) ||
			/^([A-Za-z0-9_-]{11})$/.exec(text);
		return m ? m[1] : '';
	}

	// 受信: モデレーター以上、またはサーバー(保存値・サーバー API)が送ったものだけ
	channel.onReceived(function (room, data) {
		if (!data.user || data.user.auth < 2) return;
		var id = String(data.data[0] || '');
		if (id === '' || /^[A-Za-z0-9_-]{11}$/.test(id)) show(id);
	});

	ui.menu.add({
		id: 'youtube-demo.open',
		label: 'YouTube',
		condition: function (ctx) {
			return ctx.room.my.auth >= 2;
		},
		onSelect: function () {
			ui.dialog.prompt('YouTube', '動画の URL を入力してください。空にすると閉じます。').then(function (text) {
				if (text === null) return; // キャンセル
				text = text.trim();
				var id = videoId(text);
				if (text && !id) return ui.dialog.alert('YouTube', '正しい YouTube の URL ではありません。');
				if (id) {
					channel.save([id]); // あとから入室する人のために保存
					channel.send([id]); // いまいる人に(自分にも戻ってくる)
				} else {
					channel.clear();
					channel.send(['']);
				}
			});
		},
	});
});

// 入室したときや権限が変わったときに、ボタンの表示条件を再計算する
function refreshMenu(room) {
	room.skin.menu.resolver.refresh();
}
U.chat('my-room').on('after.join#youtube-demo', refreshMenu);
U.chat('my-room').on('after.user.modi#youtube-demo', refreshMenu);
</script>

使い方

  • モデレーター以上には、入力欄のツールバーに YouTube ボタンが表示されます。会員連携を使っていないチャットルームなら、/login 管理者パスワード で管理者になって試してください。
  • URLを入力すると会話領域の右上にプレーヤーが表示され、空の値を入力すると全員の画面から閉じます。
  • 新しく入室した人には保存された値が入室時に届き、同じ動画が表示されます。

仕組み

段階 使うAPI 説明
ボタン room.skin.menu.add condition でモデレーター以上にだけ表示します。コールバックは同期関数である必要があります
入力 room.skin.dialog.prompt OKなら入力した文字列、キャンセルなら null を返すPromiseです
送信 channel.send, channel.save send はいま接続している全員(自分を含む)に送り、save はあとから入室する人のために保存します
表示 room.skin.mount.overlay 会話一覧の上に重なる領域を付け、返された関数で外します

保存された値は入室時にサーバーが権限 4 で送るため、受信側の権限チェックを通過します。各APIの詳細はスキンUI APIとチャンネルAPIと上限をご覧ください。

サーバーから再生する

サーバーREST APIで同じチャンネルに動画IDを送れば、サイトの管理画面などからも再生できます。サーバーが送ったデータは権限が 4 なので、上のコードの権限チェックを通過します。

curl -X POST https://api.uchat.io/v2/rooms/room_xxxxxxxxxxxxxxxx/events \
  -H "Authorization: Bearer uchat_..." \
  -H "Content-Type: application/json" \
  -d '{"plugin":"youtube-demo","save":true,"data":["dQw4w9WgXcQ"]}'

"save": true で送るとチャットルームに保存され、あとから入室した人も同じ動画を見られます。チャットルームに誰もいないときに送っても保存されます。閉じるには "data":[""] を保存します。APIキーは管理ページの API メニューで発行します。

注意点

  • 誰でも同じチャンネルにデータを送れます。受け取ったデータは、送信者の権限(data.user.auth)と形を必ず確認してください。
  • 重なる領域が会話を隠さないように、hostはクリックを通過させ、プレーヤーにだけ pointer-events:auto を指定します。
  • save はモデレーター以上だけが使えます。無料チャットルームは1つのチャンネルにしか保存できないため、別のチャンネルに保存すると既存の保存値は削除されます。
  • 無料チャットルームはチャンネルの送信量に上限があります。全体送信は接続者数の分だけ差し引かれ、上限を超えるとエラー 428 になります(チャンネルAPIと上限)。

読んでもよくわからない場合は お問い合わせ掲示板に質問を書き込んでください。

商号 UCHAT · 代表者 김경욱 · 事業者登録番号 141-05-32832
所在地 경기도 파주시 와석순환로 61 · 通信販売業届出番号 2013-경기파주-4485호
代表電話 010-8677-8633 · メール support@uchat.io

ⓒ 2013–2026 UCHAT. All rights reserved.