Twilio Live Integration in Vue.js

Here, we will learn how to start the livestream and watch started livestream in Twilio using vue.js.  Last article we will show how to create the live streaming with Twilio and Node.js. Here we will call the node.js apis.

Step 1: Install the following packages:

npm install twilio-video bootstrap-vue @twilio/live-player-sdk

Step 2: Create config.js file and add the following in it:

export default {
  apiURL: "http://localhost:5000",
};

Step 3: Open LiveStreamNode.vue file and add the following in it:

<template>
  <div id="container" class="container">
    <div id="stream" class="flex items-center justify-center w-full">
      <!-- video will be added here -->
    </div>
    <div class="buttons">
      <b-button
        variant="success"
        size="md"
        class="mr-5 me-5"
        @click="startStream"
        v-if="!streaming"
        >Start Stream</b-button
      >
      <b-button
        variant="danger"
        size="md"
        class="mr-5 me-5"
        @click="endStream"
        v-else
        >Leave Stream</b-button
      >
      <b-button variant="success" @click="watchStream">Watch Stream</b-button>
    </div>
  </div>
</template>
<script>
import { createLocalVideoTrack, connect } from "twilio-video"; 
import { BButton } from "bootstrap-vue";
import config from "../config";
import axios from "axios";
let liveNotification = document.createElement("div");
liveNotification.innerHTML = "LIVE";
liveNotification.id = "liveNotification";
liveNotification.classList.add(
  "absolute",
  "top-10",
  "left-48",
  "p-2",
  "bg-red-500",
  "text-white"
);
export default {
  name: "LiveStreamNode",
  components: {
    BButton,
  },
  data() {
    return {
      streaming: false,
      room: null,
      streamName:
        localStorage.getItem("roomName") ||
        "Test Name" + Math.random() * 1000000,
      identity:
        localStorage.getItem("userName") || "Shaikh" + Math.random() * 1000000,
      streamDetails: null,
    };
  },
  mounted() {
    this.addLocalVideo();
  },
  methods: {
    watchStream() {
      window.open(
        `/watchstream?playback=${this.streamDetails.player_streamer_sid}`
      );
    },
    async joinLive() {
      const tokenResponse = await fetch(`${config.apiURL}/streamerToken`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          identity: this.identity,
          room: this.streamDetails.room_sid,
        }),
      });

      const tokenData = await tokenResponse.json();
      this.room = await connect(tokenData.token);
    },
    async startStream() {
      // Create the livestream
      await axios
        .post(`${config.apiURL}/start`, { streamName: this.streamName })
        .then(({ data }) => {
          if (data.status) {
            this.streamDetails = data.data;
            this.joinLive();
            this.streaming = true;
            const stream = window.$("div#stream")[0];
            const video = document.getElementsByTagName("video")[0];
            stream.insertBefore(liveNotification, video);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    },
    async addLocalVideo() {
      const videoTrack = await createLocalVideoTrack();
      const stream = window.$("div#stream")[0];
      const trackElement = videoTrack.attach();
      stream.appendChild(trackElement);
    },
    async endStream() {
      if (this.streaming) {
        const data = {
          media_processor_sid: this.streamDetails.media_processor_sid,
          player_streamer_sid: this.streamDetails.player_streamer_sid,
          room_sid: this.streamDetails.room_sid,
        };
        const formData = new FormData();
        Object.keys(data).forEach((key) => {
          formData.append(key, data[key]);
        });
        await axios
          .post(`${config.apiURL}/end`, formData)
          .then((res) => {
            if (res.data.status === "success") {
              if (this.room) {
                this.room.disconnect();
              }
              this.streaming = false;
              liveNotification.remove();
              createLocalVideoTrack().isStopped;
              this.$toastr.success(res.data.content);
            }
          })
          .catch((error) => {
            console.log(error);
          });
      }
    },
  },
};
</script>
<style>
.bg-red-500 {
    background-color: red;
}

.absolute {
    position: absolute;
}
</style>

Step 4: Create a new folder public/livePlayer and add the following files in it:

- twilio-live-player-wasmworker-1-5-0.min.js
- twilio-live-player-wasmworker-1-5-0.min.wasm
- twilio-live-player.js
- twilio-live-player.min.js

Step 5: Open WatchStreamNode.vue file and add the following in it:

<template>
  <div class="container mx-auto mt-10 justify-center items-center text-center">
    <h1 class="text-primary">WatchStream</h1>
    <div id="player" class="mx-auto bg-gray-200 h-96 max-w-2xl"></div>

    <b-button
      variant="success"
      size="md"
      class="mr-5 me-5"
      @click="watchStream"
      v-if="!watchingStream"
      >Watch Stream</b-button
    >
    <b-button
      variant="danger"
      class="mr-5 me-5"
      size="md"
      @click="leaveStream"
      v-else
      >Leave Stream</b-button
    >
  </div>
</template>
<script>
import { Player } from "@twilio/live-player-sdk";
import { BButton } from "bootstrap-vue";
import config from "../config";
import axios from "axios";

export default {
  name: "WatchStreamNode",
  components: {
    BButton,
  },
  data() {
    return {
      token: "",
      watchingStream: false,
      player: null,
    };
  },
  mounted() {
    window.WatchStream = this;
  },
  methods: {
    async watchStream() {
      try {
        await axios
          .post(`${config.apiURL}/audienceToken`, {})
          .then(async (res) => {
            if (res.data.success) {
              this.token = res.data.token;
              const { host, protocol } = window.location;
              const player = await Player.connect(this.token, {
                playerWasmAssetsPath: `${protocol}//${host}/livePlayer`,
              });
              this.player = player;
              this.watchingStream = true;
              setTimeout(() => {
                const videoElement = document.getElementById("player");
                videoElement.appendChild(this.player.videoElement);
                this.player.play();
              }, 100);
            } else {
              this.$toastr.error(res.data.data.msg);
            }
          })
          .catch((error) => {
            this.$toastr.error(error);
          });
      } catch (error) {
        console.log(error);
      }
    },
    leaveStream() {
      if (this.player) {
        this.player.disconnect();
      }
      const streamPlayer = window.$("div#player>video")[0];
      if (streamPlayer) {
        streamPlayer.remove();
      }
      this.watchingStream = false;
    },
  },
};
</script>

Code in action:

 

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories