Onebox parser m3u8 link and play with videojs

I edit file lib\onebox\engine\video_onebox.rb to parser link that endwith m3u8.

However, when I paste the m3u8 link from an external site, the video fails to parse correctly.

If I upload a file to the website, get an m3u8 link from this site, and then paste it into the reply box and refresh the page, the video plays perfectly. However, there are some styling issues with the onebox.

Here is the code I edited.

        if file_extension == '.m3u8'
          m3u8_html_tag(escaped_url)
        else
          # Set type attribute based on file extension
          type_attribute = case file_extension
                          when '.mov'
                            'video/quicktime'
                          when '.mp4'
                            'video/mp4'
                          when '.webm'
                            'video/webm'
                          when '.ogv'
                            'video/ogg'
                          else
                            ''
                          end
        source_tag = "<source src='#{escaped_url}'"
        source_tag += " type='#{type_attribute}'" unless type_attribute.empty?
        source_tag += '>'
        <<-HTML
          <div class="onebox video-onebox">
            <video class="video-js" controls #{@options[:disable_media_download_controls] ? 'controlslist="nodownload"' : ""}>
                #{source_tag}
              <a href='#{escaped_url}'>#{@url}</a>
            </video>
          </div>
          
          HTML
        end
      end

      def m3u8_html_tag(url)
        <<-HTML
          <div>
            <script src="https://hezheng-fmm.obs.cn-north-4.myhuaweicloud.com/jsdeliver/videojs/video.min.js"></script>
            <link href="https://hezheng-fmm.obs.cn-north-4.myhuaweicloud.com/jsdeliver/videojs/video-js.css" rel="stylesheet">
            <video class="video-js" controls>
              <source src='#{url}' type='application/x-mpegURL'>
            </video>
          </div>
        HTML
      end

Here’s a video of my process.

1 Like

I have successfully utilized VideoJS for streaming video playback. This thread is now closed.

1 Like

Great! Do you think you could share the solution here, that would be helpful for others users. :+1:

2 Likes

edit this file lib/onebox/engine/video_onebox.rb
you should merge change into test-passed branch.

# frozen_string_literal: true

module Onebox
  module Engine
    class VideoOnebox
      include Engine
      # 添加对m3u8文件的匹配
      matches_regexp(%r{^(https?:)?//.*\.(mov|mp4|webm|ogv|m3u8)(\?.*)?$}i)
      def always_https?
        AllowlistedGenericOnebox.host_matches(uri, AllowlistedGenericOnebox.https_hosts)
      end
      def to_html
        # 判断是否是m3u8文件,如果是,则使用适用于Video.js的HTML模板
        if @url.match(%r{\.m3u8$})
          # 获取时间戳,并添加一段八位随机数
          randomId = Time.now.to_i.to_s + rand(100000000).to_s
          video_tag_html = <<-HTML
          <div class="onebox video-onebox videoWrap">
            <video id='#{randomId}' class="video-js vjs-default-skin vjs-16-9" controls preload="auto" width="100%" data-setup='{"fluid": true}'>
              <source src="#{@url}" type="application/x-mpegURL">
            </video>
          </div>
          HTML
        else
          # 原有处理非m3u8文件的代码保持不变
          escaped_url = ::Onebox::Helpers.normalize_url_for_output(@url)
          video_tag_html = <<-HTML
            <div class="onebox video-onebox">
              <video width='100%' height='100%' controls #{@options[:disable_media_download_controls] ? 'controlslist="nodownload"' : ""}>
                <source src='#{escaped_url}'>
                <a href='#{escaped_url}'>#{@url}</a>
              </video>
            </div>
          HTML
        end
        video_tag_html
      end

      def placeholder_html
        SiteSetting.enable_diffhtml_preview ? to_html : ::Onebox::Helpers.video_placeholder_html
      end
    end
  end
end

Rebuild docker image:
In project discourse_docker, edit file image\base\slim.Dockerfile, search # Discourse specific bits and change github link to your edited project.


rebuild image, and push it to dockerhub. change word in [].

docker build --no-cache -t mydiscourse -f slim.Dockerfile .
docker tag mydiscourse:latest [your dockerhub name]/[your image name]:[your image tag]
docker push [your dockerhub name]/[your image name]:[your image tag]

change launcher 95 line :

image="[your dockerhub name]/[your image name]:[your image tag]"

then rebuild app

./launcher rebuild app

edit theme:
Customize-> Themes → Custom CSS/HTML->Edit CSS/HTML
(If you dont have this button, you have to Export your theme then install it From your device.)

add videojs in head :

<link href="https://vjs.zencdn.net/8.10.0/video-js.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/8.10.0/video.min.js"></script></script>

add script in Body:

<script>
    setTimeout(() => {
        const domList =  document.querySelectorAll('.video-js');
        console.log(domList,'==domList');
        domList.forEach((ele, i) => {
            const videoElement = domList[i];
            const player = videojs(videoElement); // 将 DOM 元素传递给 videojs()
            player.ready(function() {
                console.log("Player is ready!");
            });
        });
    }, 200);
</script>

if you enable CSP, you should edit content security policy script src setting .

1 Like

May I change title to : Onebox parser m3u8 link and play with videojs

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.