Tích hợp kho video vào website thông qua Plugin VoD

1. Plugin VoD là gì?

Khách hàng sử dụng Bizfly Cloud VoD có thể tích hợp một kho video lên CMS của mình thông qua plugin nhúng gọi là plugin VoD. Sau khi tích hợp Plugin VoD, mỗi user trên CMS sẽ có một kho lưu trữ video riêng. Tại đây user có thể upload, quản lý, biên tập và lấy mã nhúng video để sử dụng nhu cầu.

Về tổ chức dữ liệu:

  • Dữ liệu trong kho video của user sẽ được lưu trữ vào 1 thư mục của kho video chính trên Bizfly Cloud VoD. Thư mục này được hệ thống đặt tên giống với tên của user trên CMS.

Về phân quyền sử dụng:

  • User chỉ nhìn thấy dữ liệu trên kho lưu trữ video riêng của mình thông qua plugin VoD.

  • Người quản trị có thể nhìn thấy dữ liệu của tất cả các user thông qua dashboard của Bizfly Cloud VoD.

2. Mô hình hoạt động

Khi user đăng nhập vào CMS và mở trang quản lý video, CMS Frontend sẽ chạy mã nhúng hiển thị Plugin VoD. Để khởi chạy plugin, CMS Frontend cần dùng một token để xác thực với Bizfly Cloud VoD. Mỗi user có 1 token riêng. CMS Frontend gọi lên CMS Backend để lấy token cho 1 user cụ thể .

3. Hướng dẫn tích hợp

Để tích hợp được Plugin VoD vào trang web CMS thì bạn cần:

- Lấy thông tin xác thực tại phần tích hợp CMS trên Bizfly Cloud VoD

- Lấy được token của kho video từ API của Bizfly Cloud VoD. Từ token này sẽ tích hợp được Plugin VoD vào trang web. Xem trang demo html ở dưới:

<html>
  <head>
    <title>
      Demo Plug in VoD
    </title>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/froala-editor@latest/css/froala_editor.pkgd.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>

  <!-- Load thư viện JQuery -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <!-- Load thư viện Plugin VOD -->
  <script src="https://ims.mediacdn.vn/micro/media/vod/plugins/dist/ims-plugin-media.js"></script>
  <div id="example"></div>
  <script
    type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/froala-editor@latest/js/froala_editor.pkgd.min.js"
  ></script>

  <body>
    <h1 style="text-align: center;">
      Demo Plugin VoD
    </h1>

    <hr />

    <h2>Button</h2>
    <button id="media" class="test-button">Open Plugin VOD</button>
    <hr />
    <h2>Editor</h2>
    <div id="froala-editor"></div>
  </body>
  <script>
    // Hàm lấy plugin vod token
    function getTokenFunction(callback) {
      var username = "";
      var account_suffix = "";
      var code = "";
      var scope = "";
      var url = "";

      // Create the payload as a URL-encoded string
      var payload = 'username=' + encodeURIComponent(username + account_suffix) +
                    '&grant_type=authorization_code' +
                    '&code=' + encodeURIComponent(code) +
                    '&scope=' + encodeURIComponent(scope);

      var xhr = new XMLHttpRequest();
      xhr.withCredentials = true;

      xhr.addEventListener("readystatechange", function () {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          var status = xhr.status;

          if (status === 200) {
            try {
              // Parse the JSON response
              var response = JSON.parse(xhr.responseText);
              console.log(response.message.token);
              if (response.message.token) {
                // Token is in the 'token' property of the JSON response
                callback(null, response.message.token);
              } else {
                callback(new Error("Token not found in response"), null);
              }
            } catch (error) {
              callback(new Error("Error parsing JSON response"), null);
            }
          } else {
            // Request failed
            callback(new Error("Error2 get token"), null);
          }
        } else if (xhr.readyState === XMLHttpRequest.ERROR) {
          // Request error
          callback(new Error("Error3 get token"), null);
        }
      });

      xhr.open("POST", url, true);
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xhr.send(payload);
    }

    function showPlugin() {
      // Khởi tạo Plugin VOD
      IMSWidgetMedia.init({
        locale: "vi",
        plugins: {
          name: "media",
          options: {
            getTokenFunction: getTokenFunction,
          },
          methods: {
            name: "mediaManager",
            options: {
              callback(arrMedia) {
                console.log("Callback =>", arrMedia);

                arrMedia.forEach((media) => {
                  $("#preview").append(
                    '<div style="width:500px;height:400px;">' +
                      media.embedCode +
                      "</div>"
                  );
                });
              },
            },
          },
        },
      });
    }

    // Sửa editor
    FroalaEditor.DefineIcon("VoD", {
      NAME: "VoD",
      SRC: "https://docs.bizflycloud.vn/images/icon/vod.svg",
      template: "image",
    });
    FroalaEditor.RegisterCommand("VoD", {
      title: "Open Plugin VoD",
      focus: true,
      undo: true,
      refreshAfterCallback: true,
      callback: showPlugin,
    });

    FroalaEditor.DefineIcon("post", {
      NAME: "post",
      SRC: "https://cdn-icons-png.flaticon.com/512/2198/2198963.png",
      template: "image",
    });
    FroalaEditor.RegisterCommand("post", {
      title: "Đăng bài",
      focus: true,
      undo: true,
      refreshAfterCallback: true,
      callback: showPlugin,
    });

    new FroalaEditor("div#froala-editor", {
      toolbarButtons: [
        [
          "bold",
          "italic",
          "underline",
          "paragraphFormat",
          "formatOL",
          "formatUL",
        ],
        ["undo", "redo", "html", "VoD", "post"],
      ],
    });

    // Event click vào button "Mở Plugin VOD"
    $("#media").off("click").on("click", showPlugin);
  </script>
</html>

- Sau khi thay các thông tin cần thiết từ phần hướng dẫn nhúng Plugin và trang demo ở trên, chúng ta sẽ được một trang web như hình bên dưới. Click vào nút ‘Open Plugin VoD’ trên trang demo để mở Plugin.

- Plugin VoD sẽ hiện lên như hình minh họa bên dưới

Lưu ý: Cách nhúng trực tiếp các thông tin của kho vào trang cms demo chỉ dùng để test, bởi vì nếu nhúng trực tiếp thì sẽ bị lộ thông tin tài khoản. Phía Back-End CMS nên viết một API lấy token từ Bizfly Cloud, sau đó Front-End CMS sẽ gọi vào API lấy token từ Back-End của CMS để tránh việc lộ thông tin tài khoản. Hướng dẫn viết API để lấy token từ Bizfly Cloud ở phần 3.1 dưới đây

3.1 Viết API cấp token cho user trên CMS Backend

Lấy thông tin xác thực tại phần tích hợp CMS trên Bizfly Cloud VoD

Code minh họa
Python

from flask import Flask, make_response
import requests

app = Flask(__name__)

def check_authen():
    return True

def get_username():
    return "username_1"

# Api lấy token cho plugin
@app.route("/plugin-vod-token")
def token():
    # Kiểm tra xác thực
    if not check_authen:
        return make_response("Authen Error", 401)
    
    # Xác định username
    username = get_username()

    # Khởi tạo thông tin xác thực
    account_suffix = "" # Nhập Account Suffix
    code = "" # Nhập code
    scope = "" # Nhập scope
    url = "" # Nhập url

    # Gọi sang Bizfly Cloud VoD để lấy token theo user
    payload = {'username': f"{username}{account_suffix}",
               'grant_type': 'authorization_code',
               'code': code,
               'scope': scope}
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    data = requests.post(url, headers=headers, data=payload)

    # Xử lý lấy token từ dữ liệu trả về
    token = data.json()["message"]["token"]
    response = make_response(token, 200)

    return response

if __name__ == "__main__":
 app.run()

Java

import com.squareup.okhttp.*;
import org.json.JSONObject;

public class GetToken {
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    public static String getToken() throws Exception {
        // Xác thực người dùng
        // ...
        String username = "";
        // Khởi tạo thông tin xác thực
        String accountSuffix = "";  // Nhập Account Suffix
        String code = "";  // Nhập code
        String scope = "";  // Nhập scope
        String url = "";  // Nhập url

        // Tạo thông tin payload
        JSONObject payload = new JSONObject();
        payload.put("username", username + accountSuffix);
        payload.put("grant_type", "authorization_code");
        payload.put("code", code);
        payload.put("scope", scope);

        // Tạo đối tượng OkHttpClient để gọi API
        OkHttpClient client = new OkHttpClient();

        // Tạo request
        RequestBody body = RequestBody.create(JSON, payload.toString());
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        // Thực hiện gọi API
        Response response = client.newCall(request).execute();

        // Lấy dữ liệu trả về từ API
        String responseData = response.body().string();
        JSONObject result = new JSONObject(responseData);

        // Lấy trường token
        String token = result.getJSONObject("message").getString("token");

        return token;
    }
}

NodeJS

const axios = require('axios');

async function getToken() {
  // Xác thực người dùng
  // ...
  const username = "";
  // Khởi tạo thông tin xác thực
  const accountSuffix = ""; // Nhập Account Suffix
  const code = ""; // Nhập code
  const scope = ""; // Nhập scope
  const url = ""; // Nhập url

  // Gọi sang Bizfly Cloud VoD để lấy token theo user
  const payload = {
    username: `${username}${accountSuffix}`,
    grant_type: 'authorization_code',
    code,
    scope,
  };
  const headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
  };

  const response = await axios.post(url, payload, { headers });

  // Lấy dữ liệu trả về từ API
  const result = response.data;

  // Lấy trường token
  const token = result.message.token;

  return token;
}

module.exports = getToken;

PHP


<?php

function get_token() {
    // Xác thực người dùng
    // ...
    $username = "";
    // Khởi tạo thông tin xác thực
    $account_suffix = "";  // Nhập Account Suffix
    $code = "";  // Nhập code
    $scope = "";  // Nhập scope
    $url = "";  // Nhập url

    // Tạo thông tin payload
    $payload = [
        'username' => $username . $account_suffix,
        'grant_type' => 'authorization_code',
        'code' => $code,
        'scope' => $scope,
    ];

    // Tạo thông tin headers
    $headers = [
        'Content-Type' => 'application/x-www-form-urlencoded'
    ];

    // Thực hiện gọi API bằng cURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    curl_close($ch);

    // Lấy dữ liệu trả về từ API
    $result = json_decode($response, true);

    // Lấy trường token
    $token = $result["message"]["token"];

    return $token;
}

?>

C#

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;

namespace GetToken
{
    class Program
    {
        static void Main(string[] args)
        {
            GetToken().Wait();
        }

        static async System.Threading.Tasks.Task GetToken()
        {
            // Xác thực người dùng
            // ...
            string username = "";
            // Khởi tạo thông tin xác thực
            string account_suffix = "";  // Nhập Account Suffix
            string code = "";  // Nhập code
            string scope = "";  // Nhập scope
            string url = "";  // Nhập url

            using (var client = new HttpClient())
            {
                var request = new HttpRequestMessage
                {
                    RequestUri = new Uri(url),
                    Method = HttpMethod.Post,
                };

                var payload = new Dictionary<string, string>
                {
                    { "username", $"{username}{account_suffix}" },
                    { "grant_type", "authorization_code" },
                    { "code", code },
                    { "scope", scope }
                };

                request.Content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/x-www-form-urlencoded");

                var response = await client.SendAsync(request);

                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine("Error in request");
                }

                // Lấy dữ liệu trả về từ API
                var responseContent = await response.Content.ReadAsStringAsync();
                dynamic result = JsonConvert.DeserializeObject(responseContent);

                // Lấy trường token
                string token = result.message.token;

                Console.WriteLine("Token: " + token);
            }
        }
    }
}


3.2 Cài đặt mã nhúng Plugin vào CMS

Giả sử đã triển khai thành công API lấy token trên CMS Backend tại địa chỉ http://127.0.0.1:5000/plugin-vod-token. Chúng ta tiến hành cài đặt mã nhúng Plugin VoD vào vị trí muốn hiển thị trên CMS theo code mẫu tại https://jsfiddle.net/m1bysdur/4/