All Products
Search
Document Center

ApsaraVideo Live:Memulai dengan ARTC Web SDK

Last Updated:Jun 21, 2026

ApsaraVideo Real-time Communication (ARTC) Web SDK adalah toolkit yang disediakan oleh Alibaba Cloud untuk mengembangkan aplikasi komunikasi real-time berbasis web. SDK ini memungkinkan Anda mengintegrasikan fitur berkualitas tinggi, seperti panggilan audio/video dan pesan real-time, ke dalam aplikasi web Anda dengan cepat. Panduan ini menunjukkan cara membangun aplikasi ARTC pertama Anda secara cepat.

Langkah 1: Buat aplikasi

  1. Masuk ke ApsaraVideo Live console.

  2. Pada panel navigasi kiri, pilih Live + > ApsaraVideo Real-time Communication > Applications.

  3. Klik Create Application.

  4. Masukkan instance name kustom, centang kotak Terms of Service, lalu klik Purchase Now.

  5. Setelah muncul pesan sukses, muat ulang halaman Applications untuk melihat aplikasi ApsaraVideo Real-time Communication baru Anda.

    Catatan

    Pembuatan aplikasi tidak dikenai biaya. Anda akan dikenai biaya berdasarkan penggunaan aktual dengan skema pay-as-you-go. Untuk informasi selengkapnya, lihat Billing of audio and video calls.

Langkah 2: Dapatkan Application ID dan AppKey

Setelah membuat aplikasi, temukan aplikasi tersebut di daftar aplikasi. Pada kolom Actions, klik Manage untuk membuka halaman Basic Information. Di halaman ini, temukan Application ID dan AppKey.

Langkah 3: Integrasikan SDK

  1. Integrasikan SDK.

    Script

    Pada halaman HTML Anda, sertakan skrip SDK.

    <script src="https://g.alicdn.com/apsara-media-box/imp-web-rtc/7.1.9/aliyun-rtc-sdk.js"></script>

    NPM

    Pada proyek Anda, jalankan perintah berikut untuk menginstal SDK.

    npm install aliyun-rtc-sdk --save
  2. Inisialisasi engine.

    // Pilih salah satu dari dua metode impor berikut.
    // Gunakan ini jika Anda mengimpor dari paket npm.
    import AliRtcEngine from 'aliyun-rtc-sdk';
    // Gunakan ini jika Anda menyertakan SDK dengan tag script.
    const AliRtcEngine = window.AliRtcEngine;
    // Periksa kompatibilitas browser.
    const checkResult = await AliRtcEngine.isSupported();
    if (!checkResult.support) {
      // Lingkungan saat ini tidak didukung. Minta pengguna untuk beralih atau memperbarui browser mereka.
    }
    // Buat instans engine. Anda dapat menyimpannya sebagai variabel global.
    const aliRtcEngine = AliRtcEngine.getInstance();
    
  3. Setelah membuat instans AliRtcEngine, dengarkan dan tangani event terkait.

    // Dipicu ketika pengguna lokal meninggalkan channel.
    aliRtcEngine.on('bye', (code) => {
      // `code` adalah kode alasan. Untuk detailnya, lihat referensi API.
      console.log(`bye, code=${code}`);
      // Tangani logika bisnis Anda di sini, misalnya keluar dari halaman panggilan.
    });
    // Dipicu ketika pengguna jarak jauh online.
    aliRtcEngine.on('remoteUserOnLineNotify', (userId, elapsed) => {
      console.log(`User ${userId} bergabung ke channel dalam ${elapsed} detik.`);
      // Tangani logika bisnis Anda di sini, misalnya menampilkan modul UI untuk pengguna ini.
    });
    // Dipicu ketika pengguna jarak jauh offline.
    aliRtcEngine.on('remoteUserOffLineNotify', (userId, reason) => {
      // `reason` adalah kode alasan. Untuk detailnya, lihat referensi API.
      console.log(`User ${userId} meninggalkan channel. Kode alasan: ${reason}`);
      // Tangani logika bisnis Anda di sini, misalnya menghapus modul UI untuk pengguna ini.
    });
    // Dipicu ketika status langganan aliran jarak jauh berubah.
    aliRtcEngine.on('videoSubscribeStateChanged', (userId, oldState, newState, interval, channelId) => {
      // 'oldState' dan 'newState' adalah nilai AliRtcSubscribeState.
      // Nilai: 0 (diinisialisasi), 1 (tidak berlangganan), 2 (sedang berlangganan), 3 (berlangganan).
      // `interval` adalah waktu antar perubahan status, dalam milidetik.
      console.log(`Status langganan pengguna jarak jauh ${userId} di channel ${channelId} berubah dari ${oldState} ke ${newState}.`);
      // Tangani logika untuk menonton aliran jarak jauh di sini.
      // Ketika `newState` menjadi 3, Anda dapat memutar aliran jarak jauh dengan memanggil setRemoteViewConfig.
      // Ketika `newState` menjadi 1, Anda dapat menghentikan pemutaran.
    });
    // Dipicu ketika informasi autentikasi kedaluwarsa.
    aliRtcEngine.on('authInfoExpired', () => {
      // Callback ini menunjukkan bahwa informasi autentikasi telah kedaluwarsa.
      // Dapatkan token dan data lain yang baru, lalu panggil metode refreshAuthInfo untuk memperbarui data autentikasi.
      aliRtcEngine.refreshAuthInfo({
        userId,
        token,
        timestamp
      });
    });
    // Dipicu ketika informasi autentikasi akan segera kedaluwarsa.
    aliRtcEngine.on('authInfoWillExpire', () => {
      // Callback ini dipicu 30 detik sebelum kedaluwarsa. Anda harus segera memperbarui informasi autentikasi.
      // Untuk tetap dalam sesi, dapatkan token dan data lain yang baru, lalu panggil joinChannel untuk bergabung kembali ke channel.
    });
    
  4. (Opsional) Atur mode channel. Mode default adalah mode communication. Untuk informasi selengkapnya, lihat Set the channel mode and user role.

    // Atur mode channel. Nilai yang valid: 'communication' (mode communication), 'interactive_live' (mode interaktif).
    aliRtcEngine.setChannelProfile('interactive_live');
    // Atur peran pengguna. Metode ini hanya berlaku dalam mode interaktif.
    // Nilai yang valid: 'interactive' (streamer, dapat mempublikasikan dan berlangganan aliran), 'live' (penonton, hanya dapat berlangganan aliran).
    aliRtcEngine.setClientRole('interactive');
  5. Bergabung ke channel. Untuk informasi tentang cara menghasilkan token, lihat token-based authentication. Anda dapat memilih untuk bergabung dengan satu parameter atau beberapa parameter sesuai kebutuhan.

    • Bergabung dengan satu parameter

      const userName = 'Test User 1'; // Anda dapat mengganti ini dengan username Anda. Karakter Tionghoa didukung.
      try {
        // Anda perlu mengimplementasikan fetchToken untuk mendapatkan token yang diencode Base64 dari server Anda.
        const base64Token = await fetchToken();
        await aliRtcEngine.joinChannel(base64Token, userName);
        // Berhasil bergabung ke channel. Lanjutkan dengan operasi lainnya.
      } catch (error) {
        // Gagal bergabung ke channel.
      }
    • Bergabung dengan beberapa parameter

      // Hasilkan informasi autentikasi di server Anda atau secara lokal mengikuti panduan autentikasi berbasis token.
      // PENTING: Untuk keamanan data, jangan pernah memublikasikan logika perhitungan token yang mencakup AppKey Anda kepada pengguna akhir.
      const appId = 'yourAppId'; // Dapatkan ini dari console.
      const appKey = 'yourAppKey'; // Dapatkan ini dari console. Jangan paparkan AppKey Anda di lingkungan produksi.
      const channelId = 'AliRtcDemo'; // Anda dapat mengganti ini dengan ID channel Anda. Hanya huruf dan angka yang didukung.
      const userId = 'test1'; // Anda dapat mengganti ini dengan ID pengguna Anda. Hanya huruf dan angka yang didukung.
      const userName = 'Test User 1'; // Anda dapat mengganti ini dengan username Anda. Karakter Tionghoa didukung.
      const timestamp = Math.floor(Date.now() / 1000) + 3600; // Kedaluwarsa dalam satu jam.
      try {
        const token = await generateToken(appId, appKey, channelId, userId, timestamp);
        // Bergabung ke channel. Parameter seperti token dan timestamp biasanya dikembalikan dari server.
        // Catatan: Saat memanggil metode ini, pastikan parameter channelId, userId, appId, dan timestamp sesuai dengan yang digunakan untuk menghasilkan token.
        await aliRtcEngine.joinChannel({
          channelId,
          userId,
          appId,
          token,
          timestamp,
        }, userName);
        // Berhasil bergabung ke channel. Lanjutkan dengan operasi lainnya.
      } catch (error) {
        // Gagal bergabung ke channel.
      }
  6. Ikuti langkah-langkah berikut untuk pratinjau video lokal Anda. Secara default, setelah Anda bergabung ke channel, data audio dan video lokal secara otomatis ditangkap dan dipublikasikan ke Global Realtime Transport Network (GRTN).

    1. Pada kode HTML, tambahkan elemen VIDEO dengan id localPreviewer.

      <video
        id="localPreviewer"
        muted
        style="display: block;width: 320px;height: 180px;background-color: black;"
      ></video>
    2. Panggil metode setLocalViewConfig dan berikan ID elemen untuk memulai pratinjau.

      // Parameter pertama menerima HTMLVideoElement atau ID-nya. Berikan null untuk menghentikan pratinjau.
      // Parameter kedua menentukan jenis aliran: 1 untuk aliran kamera, 2 untuk aliran berbagi layar.
      aliRtcEngine.setLocalViewConfig('localPreviewer', 1);
  7. Berlangganan aliran audio dan video jarak jauh. Secara default, setelah bergabung ke channel, SDK secara otomatis berlangganan aliran audio dan video streamer lainnya. Aliran audio diputar secara otomatis. Untuk melihat aliran kamera atau aliran berbagi layar, panggil metode setRemoteViewConfig.

    1. Pada kode HTML, tambahkan elemen DIV dengan id remoteVideoContainer sebagai wadah.

      <div id="remoteVideoContainer"></div>
    2. Dengarkan perubahan langganan aliran video jarak jauh. Saat aliran berlangganan, putar dengan memanggil metode setRemoteViewConfig. Saat tidak berlangganan, hapus elemen video.

      // Simpan elemen Video.
      const remoteVideoElMap = {};
      // Elemen wadah jarak jauh.
      const remoteVideoContainer = document.querySelector('#remoteVideoContainer');
      function removeRemoteVideo(userId) {
        const el = remoteVideoElMap[userId];
        if (el) {
          aliRtcEngine.setRemoteViewConfig(null, userId, 1);
          el.pause();
          remoteVideoContainer.removeChild(el);
          delete remoteVideoElMap[userId];
        }
      }
      // Ini adalah contoh yang sama seperti pada langkah "dengarkan dan tangani event terkait" untuk `videoSubscribeStateChanged`.
      aliRtcEngine.on('videoSubscribeStateChanged', (userId, oldState, newState, interval, channelId) => {
        // `oldState` dan `newState` bertipe AliRtcSubscribeState.
        // Nilai: 0 (diinisialisasi), 1 (tidak berlangganan), 2 (sedang berlangganan), 3 (berlangganan).
        // `interval` adalah waktu antar perubahan status, dalam milidetik.
        console.log(`Status langganan pengguna jarak jauh ${userId} di channel ${channelId} berubah dari ${oldState} ke ${newState}.`);
        
        // Contoh penanganan
        if (newState === 3) {
          const video = document.createElement('video');
          video.autoplay = true;
          video.setAttribute('style', 'display: block;width: 320px;height: 180px;background-color: black;');
          remoteVideoElMap[userId] = video;
          remoteVideoContainer.appendChild(video);
          // Parameter pertama adalah HTMLVideoElement.
          // Parameter kedua adalah ID pengguna jarak jauh.
          // Parameter ketiga menentukan jenis aliran: 1 untuk aliran kamera, 2 untuk aliran berbagi layar.
          aliRtcEngine.setRemoteViewConfig(video, userId, 1);
        } else if (newState === 1) {
          removeRemoteVideo(userId);
        }
      });
  8. Akhiri sesi dan bersihkan sumber daya.

    // Hentikan pratinjau lokal.
    await aliRtcEngine.stopPreview();
    // Tinggalkan channel.
    await aliRtcEngine.leaveChannel();
    // Hapus instans untuk melepaskan sumber daya.
    aliRtcEngine.destroy();

Demo quick start

Penting

JavaScript dalam demo ini mencakup metode generateToken untuk menghitung token. Untuk alasan keamanan, jangan pernah memublikasikan kode ini atau AppKey Anda dalam file JavaScript sisi klien, karena dapat menyebabkan kebocoran informasi dan penyalahgunaan. Kami menyarankan agar Anda melakukan penandatanganan token di server Anda dan mengambil token melalui API terotentikasi di sisi klien.

Prasyarat

Demo ini memerlukan server HTTP di lingkungan pengembangan Anda. Jika Anda belum memiliki paket npm http-server, jalankan npm install --global http-server untuk menginstalnya secara global.

Langkah 1: Buat direktori

Buat folder demo yang berisi dua file: quick.html dan quick.js.

- demo
  - quick.html
  - quick.js

Langkah 2: Edit quick.html

Salin kode berikut ke quick.html dan simpan file tersebut.

Contoh kode

<!DOCTYPE html>
<html lang="id">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Mulai cepat aliyun-rtc-sdk</title>
    <link rel="stylesheet" href="https://g.alicdn.com/code/lib/bootstrap/5.3.0/css/bootstrap.min.css" />
    <style>
      .video {
        display: inline-block;
        width: 320px;
        height: 180px;
        margin-right: 8px;
        margin-bottom: 8px;
        background-color: black;
      }
    </style>
  </head>
  <body class="container p-2">
    <h1>Mulai cepat aliyun-rtc-sdk</h1>
    <div class="toast-container position-fixed top-0 end-0 p-3">
      <div id="loginToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
          Pesan Login
          <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Tutup"></button>
        </div>
        <div class="toast-body" id="loginToastBody"></div>
      </div>
      <div id="onlineToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
          Pengguna Online
          <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Tutup"></button>
        </div>
        <div class="toast-body" id="onlineToastBody"></div>
      </div>
      <div id="offlineToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
          Pengguna Offline
          <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Tutup"></button>
        </div>
        <div class="toast-body" id="offlineToastBody"></div>
      </div>
    </div>
    <div class="row mt-3">
      <div class="col-6">
        <form id="loginForm">
          <div class="form-group mb-2">
            <label for="channelId" class="form-label">ID Saluran</label>
            <input class="form-control" id="channelId" />
          </div>
          <div class="form-group mb-2">
            <label for="userId" class="form-label">ID Pengguna</label>
            <input class="form-control" id="userId" />
          </div>
          <button id="joinBtn" type="submit" class="btn btn-primary mb-2">Gabung Saluran</button>
          <button id="leaveBtn" type="button" class="btn btn-secondary mb-2" disabled>Tinggalkan Saluran</button>
        </form>
        <div class="mt-3">
          <h4>Pratinjau Lokal</h4>
          <video
            id="localPreviewer"
            muted
            class="video"
          ></video>
        </div>
      </div>
      <div class="col-6">
        <h4>Pengguna Jarak Jauh</h4>
        <div id="remoteVideoContainer"></div>
      </div>
    </div>
    <script src="https://g.alicdn.com/code/lib/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://g.alicdn.com/code/lib/bootstrap/5.3.0/js/bootstrap.min.js"></script>
<script src="https://g.alicdn.com/apsara-media-box/imp-web-rtc/7.1.9/aliyun-rtc-sdk.js"></script>
    <script src="./quick.js"></script>
  </body>
</html>

Langkah 3: Edit quick.js

Salin kode berikut ke quick.js. Tempel application ID dan AppKey Anda ke variabel yang ditentukan dan simpan file tersebut.

Contoh kode

function hex(buffer) {
  const hexCodes = [];
  const view = new DataView(buffer);
  for (let i = 0; i < view.byteLength; i += 4) {
    const value = view.getUint32(i);
    const stringValue = value.toString(16);
    const padding = '00000000';
    const paddedValue = (padding + stringValue).slice(-padding.length);
    hexCodes.push(paddedValue);
  }
  return hexCodes.join('');
}
async function generateToken(appId, appKey, channelId, userId, timestamp) {
  const encoder = new TextEncoder();
  const data = encoder.encode(`${appId}${appKey}${channelId}${userId}${timestamp}`);
  const hash = await crypto.subtle.digest('SHA-256', data);
  return hex(hash);
}
function showToast(baseId, message) {
  $(`#${baseId}Body`).text(message);
  const toast = new bootstrap.Toast($(`#${baseId}`));
  toast.show();
}
// Masukkan application ID dan AppKey Anda.
const appId = '';
const appKey = '';
AliRtcEngine.setLogLevel(0);
let aliRtcEngine;
const remoteVideoElMap = {};
const remoteVideoContainer = document.querySelector('#remoteVideoContainer');
function removeRemoteVideo(userId, type = 'camera') {
  const vid = `${type}_${userId}`;
  const el = remoteVideoElMap[vid];
  if (el) {
    aliRtcEngine.setRemoteViewConfig(null, userId, type === 'camera' ? 1: 2);
    el.pause();
    remoteVideoContainer.removeChild(el);
    delete remoteVideoElMap[vid];
  }
}
function listenEvents() {
  if (!aliRtcEngine) {
    return;
  }
  // Dipicu ketika pengguna jarak jauh online.
  aliRtcEngine.on('remoteUserOnLineNotify', (userId, elapsed) => {
    console.log(`User ${userId} bergabung ke channel dalam ${elapsed} detik.`);
    // Tangani logika bisnis Anda di sini, misalnya menampilkan modul UI untuk pengguna ini.
    showToast('onlineToast', `User ${userId} online.`);
  });
  // Dipicu ketika pengguna jarak jauh offline.
  aliRtcEngine.on('remoteUserOffLineNotify', (userId, reason) => {
    // `reason` adalah kode alasan. Untuk detailnya, lihat referensi API.
    console.log(`User ${userId} meninggalkan channel. Kode alasan: ${reason}`);
    // Tangani logika bisnis Anda di sini, misalnya menghapus modul UI untuk pengguna ini.
    showToast('offlineToast', `User ${userId} offline.`);
    removeRemoteVideo(userId, 'camera');
    removeRemoteVideo(userId, 'screen');
  });
  aliRtcEngine.on('bye', code => {
    // `code` adalah kode alasan. Untuk detailnya, lihat referensi API.
    console.log(`bye, code=${code}`);
    // Tangani logika bisnis Anda di sini, misalnya keluar dari halaman panggilan.
    showToast('loginToast', `Anda telah meninggalkan channel. Kode alasan: ${code}`);
  });
  aliRtcEngine.on('videoSubscribeStateChanged', (userId, oldState, newState, interval, channelId) => {
    // 'oldState' dan 'newState' adalah nilai AliRtcSubscribeState.
    // Nilai: 0 (diinisialisasi), 1 (tidak berlangganan), 2 (sedang berlangganan), 3 (berlangganan).
    // `interval` adalah waktu antar perubahan status, dalam milidetik.
    console.log(`Status langganan pengguna jarak jauh ${userId} di channel ${channelId} berubah dari ${oldState} ke ${newState}.`);
    const vid = `camera_${userId}`;
    // Contoh penanganan
    if (newState === 3) {
      const video = document.createElement('video');
      video.autoplay = true;
      video.className = 'video';
      remoteVideoElMap[vid] = video;
      remoteVideoContainer.appendChild(video);
      // Parameter pertama adalah HTMLVideoElement.
      // Parameter kedua adalah ID pengguna jarak jauh.
      // Parameter ketiga menentukan jenis aliran: 1 untuk aliran kamera, 2 untuk aliran berbagi layar.
      aliRtcEngine.setRemoteViewConfig(video, userId, 1);
    } else if (newState === 1) {
      removeRemoteVideo(userId, 'camera');
    }
  });
  aliRtcEngine.on('screenShareSubscribeStateChanged', (userId, oldState, newState, interval, channelId) => {
    // 'oldState' dan 'newState' adalah nilai AliRtcSubscribeState.
    // Nilai: 0 (diinisialisasi), 1 (tidak berlangganan), 2 (sedang berlangganan), 3 (berlangganan).
    // `interval` adalah waktu antar perubahan status, dalam milidetik.
    console.log(`Status langganan aliran berbagi layar untuk pengguna ${userId} di channel ${channelId} berubah dari ${oldState} ke ${newState}.`);
    const vid = `screen_${userId}`;
    // Contoh penanganan
    if (newState === 3) {
      const video = document.createElement('video');
      video.autoplay = true;
      video.className = 'video';
      remoteVideoElMap[vid] = video;
      remoteVideoContainer.appendChild(video);
      // Parameter pertama adalah HTMLVideoElement.
      // Parameter kedua adalah ID pengguna jarak jauh.
      // Parameter ketiga menentukan jenis aliran: 1 untuk aliran kamera, 2 untuk aliran berbagi layar.
      aliRtcEngine.setRemoteViewConfig(video, userId, 2);
    } else if (newState === 1) {
      removeRemoteVideo(userId, 'screen');
    }
  });
}
$('#loginForm').submit(async e => {
  // Cegah aksi pengiriman formulir default.
  e.preventDefault();
  const channelId = $('#channelId').val();
  const userId = $('#userId').val();
  const timestamp = Math.floor(Date.now() / 1000) + 3600 * 3;
  if (!channelId || !userId) {
    showToast('loginToast', 'Informasi tidak lengkap.');
    return;
  }
  aliRtcEngine = AliRtcEngine.getInstance();
  listenEvents();
  try {
    const token = await generateToken(appId, appKey, channelId, userId, timestamp);
    // Atur mode channel. Nilai yang valid: 'communication' (mode communication), 'interactive_live' (mode interaktif).
    aliRtcEngine.setChannelProfile('communication');
    // Atur peran pengguna. Metode ini hanya berlaku dalam mode interaktif.
    // Nilai yang valid: 'interactive' (streamer, dapat mempublikasikan dan berlangganan aliran), 'live' (penonton, hanya dapat berlangganan aliran).
    // await aliRtcEngine.setClientRole('interactive');
    // Bergabung ke channel. Parameter seperti token dan timestamp biasanya dikembalikan dari server.
    await aliRtcEngine.joinChannel(
      {
        channelId,
        userId,
        appId,
        token,
        timestamp,
      },
      userId
    );
    showToast('loginToast', 'Berhasil bergabung ke channel.');
    $('#joinBtn').prop('disabled', true);
    $('#leaveBtn').prop('disabled', false);
    // Mulai pratinjau lokal.
    aliRtcEngine.setLocalViewConfig('localPreviewer', 1);
  } catch (error) {
    console.log('Gagal bergabung ke channel.', error);
    showToast('loginToast', 'Gagal bergabung ke channel.');
  }
});
$('#leaveBtn').click(async () => {
  Object.keys(remoteVideoElMap).forEach(vid => {
    const arr = vid.split('_');
    removeRemoteVideo(arr[1], arr[0]);
  });
  // Hentikan pratinjau lokal.
  await aliRtcEngine.stopPreview();
  // Tinggalkan channel.
  await aliRtcEngine.leaveChannel();
  // Hapus instans.
  aliRtcEngine.destroy();
  aliRtcEngine = undefined;
  $('#joinBtn').prop('disabled', false);
  $('#leaveBtn').prop('disabled', true);
  showToast('loginToast', 'Telah meninggalkan channel.');
});

Langkah 4: Jalankan demo

  1. Pada terminal Anda, buka folder demo dan jalankan http-server -p 8080 untuk menjalankan server HTTP.

  2. Buka tab browser baru dan arahkan ke localhost:8080/quick.html. Masukkan Channel ID dan User ID, lalu klik Join Channel.

  3. Buka tab browser kedua dan arahkan ke localhost:8080/quick.html. Masukkan Channel ID yang sama tetapi User ID yang berbeda, lalu klik Join Channel.

  4. Pastikan aliran media dari pengguna lain secara otomatis dilanggan dan ditampilkan di halaman.