You need to enable JavaScript to run this app. 在Laravel中如何流式播放HLS、m3u8格式的视频?
优惠活动
大模型
产品
解决方案
定价
更多

在Laravel中如何流式播放HLS、m3u8格式的视频?

m3u8格式视频播放与下载实现方案

播放功能修复与优化

你现有代码的核心问题是加载m3u8资源时写死了固定路径,没有调用实际存储的视频路径,优化后的前端代码实现点击按钮才触发播放,避免页面加载时占用多余带宽:

@if( $item->media_type=='v')
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<button id="play_{{ $item->id }}" style="margin-right: 10px;">播放视频</button>
<button id="download_{{ $item->id }}">下载视频</button>
<video id="video_{{ $item->id }}" controls width="200px" height="200px" style="display: none; margin-top: 10px;"></video>
<script>
// 播放逻辑
document.getElementById('play_{{ $item->id }}').addEventListener('click', function () {
    const video = document.getElementById('video_{{ $item->id }}')
    const realUrl = 'https://cdn.kenan.net/{{ $item->media_path }}'
    video.style.display = 'block'

    if (Hls.isSupported()) {
        const hls = new Hls()
        hls.loadSource(realUrl)
        hls.attachMedia(video)
        hls.on(Hls.Events.MANIFEST_PARSED, function () {
            video.play()
        })
    } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
        video.src = realUrl
        video.addEventListener('canplay', function () {
            video.play()
        })
    }
})

// 下载触发逻辑
document.getElementById('download_{{ $item->id }}').addEventListener('click', function () {
    window.location.href = '/video/download?path={{ urlencode($item->media_path) }}'
})
</script>
@endif

后端下载功能实现

m3u8是分片视频索引文件,前端无法直接下载为可播放的视频文件,需要通过laravel-ffmpeg在后端将m3u8转码为MP4后再提供下载,参考代码如下:

控制器代码

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use ProtoneMedia\LaravelFFMpeg\Support\FFMpeg;
use Illuminate\Support\Facades\Storage;

class VideoController extends Controller
{
    public function download(Request $request)
    {
        $mediaPath = $request->input('path');
        $fullM3u8Url = 'https://cdn.kenan.net/' . $mediaPath;
        $saveName = pathinfo($mediaPath, PATHINFO_FILENAME) . '.mp4';
        $tempSavePath = 'tmp/' . $saveName;

        // 转码为MP4保存到临时目录
        FFMpeg::openUrl($fullM3u8Url)
            ->export()
            ->toDisk('public')
            ->inFormat(new \FFMpeg\Format\Video\X264('aac'))
            ->save($tempSavePath);

        // 返回下载响应,下载完成后自动删除临时文件
        return response()
            ->download(Storage::disk('public')->path($tempSavePath), $saveName)
            ->deleteFileAfterSend(true);
    }
}

路由配置

在routes/web.php中添加下载路由:

Route::get('/video/download', [\App\Http\Controllers\VideoController::class, 'download']);

注意事项

  • 确保你的服务器已经正确安装FFmpeg环境,否则laravel-ffmpeg无法正常执行转码操作
  • 大体积视频转码耗时较长,建议配合队列异步处理,避免HTTP请求超时
  • 可根据业务需要添加权限校验逻辑,避免视频资源被未授权用户下载

内容的提问来源于stack exchange,提问作者black man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 02:36:04