7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

1. はじめに

こんにちは、普段はしょうもないウェブツールなどを作ったりIT関係のブログを書いたりしているなりかくんです。

今回は、Agoraというサービスを使って画面共有ツールを作りたいと思います。
この記事は、V-CUBE Advent Calendar 2022の12日目の記事です。

2. Agoraってなに?

まず最初に「Agoraってなんだよ。」と思った方向けに簡単に説明させていただきます。
Agoraというのは、スマホアプリやWebサイトに、ビデオや音声通話・ライブ配信を簡単に実装できるSDKツールです。
例えば、Discordのような音声通話やビデオ通話・画面共有の機能を簡単に搭載することが出来ます。

3. サンプルプログラムが豊富

Agoraでは、サンプルプログラムが非常に豊富に用意されています。細かくは紹介しませんが一部紹介しておきます。

3-1. Web系のサンプルプログラム

機能 サンプルプログラム
ライブ配信をする https://github.com/AgoraIO/API-Examples-Web/blob/main/Demo/basicLive
ビデオ通話をする https://github.com/AgoraIO/API-Examples-Web/blob/main/Demo/basicVideoCall
画面共有をする https://github.com/AgoraIO/API-Examples-Web/blob/main/Demo/shareTheScreen

3-2. 各OSの例

プラットフォーム 言語 サンプルプログラム
Android Java https://github.com/AgoraIO/API-Examples/blob/main/Android/APIExample
iOS Swift https://github.com/AgoraIO/API-Examples/blob/main/iOS/APIExample
macOS Swift https://github.com/AgoraIO/API-Examples/blob/main/macOS
Windows C++ https://github.com/AgoraIO/API-Examples/blob/main/windows

4. 早速作る

では、さっそく画面共有ツールを作ってみます。今回は、先ほど紹介した画面共有のサンプルプログラムを少しいじってシンプルにしました。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Share The Screen Agora</title>
    <style>
        .player {
            width: 480px;
            height: 320px;
        }
        .player-name {
            margin: 8px 0;
        }
        @media (max-width: 640px) {
            .player {
                width: 320px;
                height: 240px;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <div class="row video-group">
        <div class="col">
            <p id="local-player-name" class="player-name"></p>
            <div id="local-player" class="player"></div>
        </div>
        <div class="w-100"></div>
        <div class="col">
            <div id="remote-playerlist"></div>
        </div>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://download.agora.io/sdk/release/AgoraRTC_N.js"></script>
<script src="./videoShare.js"></script>
</body>
</html>
videoShare.js
let client = AgoraRTC.createClient({
    mode: "rtc",
    codec: "vp8"
});
AgoraRTC.enableLogUpload();
let localTracks = {
    screenVideoTrack: null,
    audioTrack: null,
    screenAudioTrack: null
};
let options = {
    appid: "AppID",
    channel: "room1",
    uid: null,
    token: null
};

join();

async function join() {
    client.on("user-published", handleUserPublished);
    client.on("user-unpublished", handleUserUnpublished);
    let screenTrack;
    [options.uid, localTracks.audioTrack, screenTrack] = await Promise.all([
        client.join(options.appid, options.channel, options.token || null, options.uid || null),
        AgoraRTC.createMicrophoneAudioTrack(), AgoraRTC.createScreenVideoTrack({
            encoderConfig: "720p"
        }, "auto")]);
    if (screenTrack instanceof Array) {
        localTracks.screenVideoTrack = screenTrack[0];
        localTracks.screenAudioTrack = screenTrack[1];
    } else {
        localTracks.screenVideoTrack = screenTrack;
    }
    localTracks.screenVideoTrack.play("local-player");
    $("#local-player-name").text(`localVideo(${options.uid})`);
    localTracks.screenVideoTrack.on("track-ended", () => {
        localTracks.screenVideoTrack && localTracks.screenVideoTrack.close();
        localTracks.screenAudioTrack && localTracks.screenAudioTrack.close();
        localTracks.audioTrack && localTracks.audioTrack.close();
    });
    if (localTracks.screenAudioTrack == null) {
        await client.publish([localTracks.screenVideoTrack, localTracks.audioTrack]);
    } else {
        await client.publish([localTracks.screenVideoTrack, localTracks.audioTrack, localTracks.screenAudioTrack]);
    }
}
async function subscribe(user, mediaType) {
    const uid = user.uid;
    await client.subscribe(user, mediaType);
    if (mediaType === 'video') {
        const player = $(`
      <div id="player-wrapper-${uid}">
        <p class="player-name">remoteUser(${uid})</p>
        <div id="player-${uid}" class="player"></div>
      </div>
    `);
        $("#remote-playerlist").append(player);
        user.videoTrack.play(`player-${uid}`);
    }
    if (mediaType === 'audio') {
        user.audioTrack.play();
    }
}
function handleUserPublished(user, mediaType) {
    subscribe(user, mediaType);
}
function handleUserUnpublished(user, mediaType) {
    if (mediaType === 'video') {
        const id = user.uid;
        $(`#player-wrapper-${id}`).remove();
    }
}

実際に動かしてみると、ブラウザを開いたら共有する画面を選択する画面が表示されます。そして、画面を選択します。
image.png
すると、共有している画面が表示されます。もちろん音声も共有できます。
image.png
別のブラウザから同じページを開いてみると、共有されている画面を表示することが出来ます。
image.png
また、複数人の同時共有も可能です。
image.png
また、iOSからこのページを開くと、しっかり共有された画面を表示することが出来ました。
こんな簡単に画面共有ツールを作れるのは最強ですね!

5. さいごに

今回は、サンプルプログラムを利用させていただき画面共有ツールを作ってみました。いかがでしたでしょうか。
作ったゲームなどのボイスチャットなどにも使えるみたいです。ぜひ使ってみてください!

7
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?