基于 Web 实现 m3u8 视频播放的简单应用示例

发布时间 2023-05-31 13:34:20作者: 飞仔FeiZai

基于 Web 实现 m3u8 视频播放的简单应用示例

实现思路

将视频(MP4 等)转换为 M3U8 视频的服务,可以按照以下步骤进行操作:

  1. 将视频(MP4 等)转换为 M3U8:在服务中,使用适当的工具(如 FFmpeg)将接收到的视频(MP4 等)转换为 M3U8 格式。这将生成一个包含视频流的 M3U8 文件以及相应的分段(TS)文件。

  2. 提供边下边播服务:将生成的 M3U8 文件和分段文件存储在适当的位置(如服务器上的文件夹或云存储服务中)。然后,可以通过将这些文件的 URL 提供给前端,使前端能够通过边下边播的方式逐段加载和播放视频。

  3. 前端实现 M3U8 播放器:在前端,可以使用现有的视频播放器库(如 video.js、plyr.js 等)或基于 HLS(HTTP Live Streaming)协议的播放器库(如 hls.js)来实现 M3U8 视频的播放器。这些库可以通过提供 M3U8 文件的 URL 来加载和播放视频。

一、将视频(MP4 等)转换为 M3U8 视频

使用 Python 实现将 MP4 视频转换为 M3U8 视频,按照以下步骤进行操作:

  1. 安装所需的库:首先,确保已安装所需的库。在 Python 中,可以使用 ffmpeg-python 库来与 FFmpeg 进行交互,以执行视频转换操作。可以使用以下命令安装该库:
pip install ffmpeg-python
  1. 导入库和设置转换函数:在 Python 代码中,导入 ffmpeg 模块,并创建一个函数,用于将 MP4 转换为 M3U8。以下是一个示例代码:
import ffmpeg

def convert_mp4_to_m3u8(input_file, output_file):
    """
    Converts an MP4 file to an M3U8 file using ffmpeg.
    Args:
        input_file (str): The path to the input MP4 file.
        output_file (str): The path to the output M3U8 file.
    Returns:
        bool: True if the conversion was successful, False otherwise.
    """
    try:
        ffmpeg.input(input_file).output(output_file, format='hls', hls_time=10, hls_segment_type='mpegts').run()
        return True
    except ffmpeg.Error as e:
        print(f"An error occurred during video conversion: {e.stderr}")
        return False

在这个示例代码中,convert_mp4_to_m3u8 函数接受输入文件路径和输出文件路径作为参数。它使用 FFmpeg 将输入文件转换为 M3U8 格式,并将分段(TS)文件输出到指定的输出文件路径。

二、实现 HTTP 服务器,提供 M3U8 视频的访问

方法一、使用 Python 标准库中的 http.server 模块

这个模块提供了一个简单的 HTTP 服务器,可以处理 GET 和 HEAD 请求,并可以为客户端提供静态文件。

以下是一个简单的示例代码,可以启动一个 HTTP 服务器并为客户端提供视频等资源的访问:

import http.server
import socketserver

PORT = 8000

Handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

在这个示例中,创建了一个 http.server.SimpleHTTPRequestHandler 处理程序,它可以处理 GET 和 HEAD 请求,并可以为客户端提供静态文件。然后,使用 socketserver.TCPServer 创建一个 TCP 服务器,并将处理程序传递给它。最后,调用 serve_forever() 方法开始监听来自客户端的请求。

将视频等资源放在服务器的根目录下,例如 ./video.m3u8,客户端可以通过浏览器访问 http://localhost:8000/video.m3u8 来获取该资源。客户端也可以使用其他 HTTP 客户端程序(例如 curl 或者 wget)来访问资源。

不过需要注意的是,这种方式只适合提供小型的静态文件。如果要提供大型视频等资源,最好使用专门的服务器软件来处理,例如 Apache 或 Nginx。

方法二、使用 Flask 框架

Flask 框架可以提供一种更为灵活的方式来实现视频等静态资源的访问。下面是一个简单的示例代码:

from flask import Flask, send_from_directory

app = Flask(__name__)

@app.route('/<path:path>')
def static_file(path):
    return send_from_directory('.', path)

if __name__ == '__main__':
    app.run(port=8000)

在这个示例中,定义了一个名为 static_file 的路由,它可以处理所有的 HTTP GET 请求,并使用 send_from_directory 函数返回请求的文件。在这里,将请求的文件从当前目录中返回。如果要返回其他目录下的文件,可以将 send_from_directory 函数的第一个参数设置为目录的路径。

要访问视频等静态资源,可以将它们放在与 Flask 应用程序相同的目录中,并使用相对路径作为 URL。例如,如果视频文件名为 video.m3u8,可以使用 http://localhost:8000/video.m3u8 访问该文件。

需要注意的是,这种方式也适用于小型的静态文件。如果要提供大型视频等资源,最好使用专门的服务器软件来处理,例如 Apache 或 Nginx。另外,这里的示例代码只提供了最简单的静态资源访问功能,如果需要更高级的功能(例如缓存控制、安全性等),可以使用 Flask 扩展或者在代码中自行实现。

三、Web 前端播放 M3U8 视频

M3U8 是一种基于 HTTP Live Streaming (HLS) 协议的视频流播放格式(在播放 M3U8 文件时需要将视频文件和 M3U8 文件都放在 HTTP 服务器上,并通过 HTTP 协议进行访问)。要在 Web 前端中实现 M3U8 播放器,可以使用一些开源的 JavaScript 库,例如 hls.jsvideo.js

hls.js 是一个基于 JavaScript 实现的 M3U8 播放器库。它可以自动检测浏览器是否支持 HLS,如果不支持则使用 Flash 播放器来进行播放。以下是一个使用 hls.js 的示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>hls.js player example</title>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  </head>
  <body>
    <video id="video" controls></video>
    <script>
      var video = document.getElementById("video");
      if (Hls.isSupported()) {
        var hls = new Hls();
        hls.loadSource("http://127.0.0.1:8000/path/to/video.m3u8");
        hls.attachMedia(video);
        hls.on(Hls.Events.MANIFEST_PARSED, function () {
          // video.play();
        });
      } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
        video.src = "http://127.0.0.1:8000/path/to/video.m3u8";
        video.addEventListener("loadedmetadata", function () {
          // video.play();
        });
      }
    </script>
  </body>
</html>

在这个示例中,首先��页面中引入了 hls.js 库。然后,创建一个 HTML5 video 元素,并为它设置了 controls 属性,以便用户可以控制视频的播放。

接着,使用 Hls.isSupported() 方法检测浏览器是否支持 HLS。如果支持,则创建一个 Hls 对象,并使用 loadSource 方法加载 M3U8 文件。然后,使用 attachMedia 方法将 video 元素附加到 Hls 对象上,并在 MANIFEST_PARSED 事件触发时开始播放视频。

如果浏览器不支持 HLS,就检测是否支持 application/vnd.apple.mpegurl 格式。如果支持,则为 video 元素的 src 属性设置 M3U8 文件的路径,并在 loadedmetadata 事件触发时开始播放视频。

除了 hls.js,还有一些其他的 JavaScript 库可以用来实现 M3U8 播放器,例如 video.js。下面是一个使用 video.js 的示例代码:

<!DOCTYPE html>
<html>
  <head>
    <title>video.js player example</title>
    <link href="https://vjs.zencdn.net/8.3.0/video-js.css" rel="stylesheet" />
    <script src="https://vjs.zencdn.net/8.3.0/video.min.js"></script>
  </head>
  <body>
    <video id="video" class="video-js vjs-default-skin" controls></video>
    <script>
      var video = videojs("video", {
        techOrder: ["html5", "flash"],
        sources: [
          {
            src: "http://127.0.0.1:8000/path/to/video.m3u8",
            type: "application/x-mpegURL",
          },
        ],
      });
      // video.play();
    </script>
  </body>
</html>

在这个示例中,首先引入了 video.js 的 CSS 和 JavaScript 文件。然后,创建了一个 HTML5 video 元素,并为它设置了 class 属性,以便应用 video.js 的默认样式。

接着,使用 videojs 函数创建一个 video.js 对象,并为其指定了 techOrdersources 选项。techOrder 选项指定了播放视频时使用的技术顺序,如果浏览器不支持 HLS,则会使用 Flash 播放器来进行播放。sources 选项指定了待播放的 M3U8 文件的路径和类型。

最后,调用 play 方法开始播放视频。