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と上限)。
読んでもよくわからない場合は お問い合わせ掲示板に質問を書き込んでください。