
下面是一份详细、实操性强的 《PHP直播系统搭建教程》,适合希望从源码层面或框架层面搭建完整直播平台的开发者。 本文将从系统结构、环境部署、推拉流配置、PHP服务端开发、前端播放集成等角度讲解。
一个完整的 PHP直播系统 一般由以下五个核心模块组成:

php直播系统搭建教程
已思考 6s
下面是一份实操性强、可直接复制运行的 PHP + 流媒体 直播系统搭建指南。覆盖环境、流媒体服务器选择与配置、PHP 后端核心代码示例、前端播放集成、鉴权、部署与扩展建议。直接照做即可得到一个可推流、可观看、带基本鉴权与房间管理的直播系统原型。
rtmp://stream.example.com/live/streamkey)。
下面给出最简化的 SQL,支持用户与直播房间、流 key 管理、观看统计。
CREATE TABLE `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(64) NOT NULL,
`password_hash` VARCHAR(255) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE `rooms` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`owner_id` INT NOT NULL,
`title` VARCHAR(255),
`stream_key` VARCHAR(64) NOT NULL,
`is_live` TINYINT(1) DEFAULT 0,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX(owner_id),
FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE TABLE `views` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`room_id` INT NOT NULL,
`user_id` INT NULL,
`ts` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX(room_id),
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE
);实际系统还需礼物、弹幕、调度、日志表等。
安装 nginx + nginx-rtmp 模块(在 Ubuntu 通常编译或用已打包版本)。
在 nginx.conf 中加入 rtmp 段:
# nginx.conf (只展示 rtmp 部分)
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
# 允许推流鉴权(可选): on_publish 指向内部 HTTP 验证 URL
on_publish http://127.0.0.1:9000/auth/on_publish;
on_publish_done http://127.0.0.1:9000/auth/on_publish_done;
# 将流导出为 HLS
hls on;
hls_path /var/www/hls;
hls_fragment 3s;
hls_playlist_length 15s;
}
}
}on_publish 用于推流前后调用你的 PHP 鉴权接口(返回 2xx 表示允许)。
SRS 的 conf/srs.conf(极简):
listen 1935;
max_connections 1000;
vhost __defaultVhost__ {
mode static;
min_latency on;
hls {
enabled on;
hls_path ./objs/nginx/html/hls;
hls_fragment 3;
hls_window 15;
}
http_api {
enabled on;
listen 1985;
}
rtc {
enabled on;
}
}SRS 支持 HTTP API,用于获取流状态、断线回调、转码等。生产环境建议阅读官方文档调参。
generate_stream_key.php(仅示例逻辑):
<?php
// 简单示例,生产请用更强随机与权限校验
function gen_stream_key($userId) {
return bin2hex(random_bytes(16)) . '-' . $userId;
}
// 保存到 rooms 表(PDO 示例)
$pdo = new PDO('mysql:host=127.0.0.1;dbname=live', 'root', 'pwd');
$userId = 1; // 假设
$streamKey = gen_stream_key($userId);
$stmt = $pdo->prepare("INSERT INTO rooms (owner_id, title, stream_key) VALUES (?, ?, ?)");
$stmt->execute([$userId, '我的直播间', $streamKey]);
echo "stream_key: $streamKey\n";当 nginx-rtmp 收到推流尝试,会 POST 一些参数到你配置的 URL。示例 on_publish_auth.php:
<?php
// 接收 nginx-rtmp 的回调(on_publish)
$stream = $_POST['name'] ?? ''; // stream key
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
header('Content-Type: text/plain');
// 简单验证:检查 stream 存在并且对应 owner
$pdo = new PDO('mysql:host=127.0.0.1;dbname=live', 'root', 'pwd');
$stmt = $pdo->prepare("SELECT id FROM rooms WHERE stream_key = ? LIMIT 1");
$stmt->execute([$stream]);
$room = $stmt->fetch(PDO::FETCH_ASSOC);
if ($room) {
http_response_code(200);
echo "OK";
} else {
http_response_code(403);
echo "Forbidden";
}nginx-rtmp 要求 2xx 才允许推流。
生成短期 token 防止未授权分享真实播放地址。
<?php
function create_play_token($roomId, $secret, $expireSec=300) {
$expire = time() + $expireSec;
$payload = $roomId . '|' . $expire;
$sig = hash_hmac('sha256', $payload, $secret);
return base64_encode($payload . '|' . $sig);
}
function verify_play_token($token, $secret) {
$raw = base64_decode($token);
list($roomId, $expire, $sig) = explode('|', $raw);
if (time() > (int)$expire) return false;
$expected = hash_hmac('sha256', $roomId . '|' . $expire, $secret);
return hash_equals($expected, $sig) ? intval($roomId) : false;
}播放页请求先向 PHP 获取 play_token,PHP 验证用户权限后返回 token,播放端把 token 加到 HLS/FLV 请求(如 ?token=xxxx),Nginx 或后端再校验 token 并返回流。
适用于从流媒体服务器导出的 FLV(例如通过 SRS 的 http-flv)。
<!doctype html>
<html>
<head><meta charset="utf-8"><title>FLV Player</title></head>
<body>
<video id="videoElement" controls autoplay playsinline style="width:100%;max-width:720px"></video>
<script src="https://unpkg.com/flv.js@latest/dist/flv.min.js"></script>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://stream.example.com/live/room123.flv?token=PASTE_TOKEN'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
</body>
</html><video id="hlsVideo" controls autoplay style="width:100%;max-width:720px"></video>
<script src="https://unpkg.com/hls.js@latest"></script>
<script>
var video = document.getElementById('hlsVideo');
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource('https://stream.example.com/hls/room123.m3u8?token=PASTE_TOKEN');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'https://stream.example.com/hls/room123.m3u8?token=PASTE_TOKEN';
video.addEventListener('loadedmetadata',function(){ video.play(); });
}
</script>Swoole、Ratchet 或将即时功能交给 Node.js。
stream_key。
rtmp://stream.example.com/live/{stream_key} 推流。
on_publish 到 PHP 验证 stream_key。验证通过后开始接收流并同时产出 HLS/FLV。
.m3u8、FLV URL 是否可访问、浏览器控制台和流媒体服务器日志。
ffmpeg 本地测试推流与转码(ffmpeg -re -i sample.mp4 -c copy -f flv rtmp://...)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。