1.没置顶的消息,到最上面去了 2.无法转发图片 3.用户ID 是一串字母+数字 4.视频无法显示 5.消息无法置顶 6.可以引用文字,无法艾特用户 7.图片点开只能显示一半 8.转发不能多选,只能一个个转发 9.转发有转发提示,需取消
This commit is contained in:
Vendored
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
const WEB_MEDIA_STREAM_ROOT = '/opt/im-server/media';
|
||||
|
||||
function failMediaStream(int $status, string $message): never
|
||||
{
|
||||
http_response_code($status);
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
header('Cache-Control: no-store');
|
||||
echo $message;
|
||||
exit;
|
||||
}
|
||||
|
||||
$url = trim((string)($_GET['url'] ?? ''));
|
||||
if ($url === '') {
|
||||
failMediaStream(400, '缺少视频地址');
|
||||
}
|
||||
|
||||
$path = rawurldecode((string)(parse_url($url, PHP_URL_PATH) ?: ''));
|
||||
if (!preg_match('#^/fs/[0-9]+/[A-Za-z0-9_./ -]+$#', $path) || str_contains($path, '..')) {
|
||||
failMediaStream(400, '视频地址不合法');
|
||||
}
|
||||
|
||||
$root = realpath(WEB_MEDIA_STREAM_ROOT);
|
||||
$fullPath = realpath(rtrim(WEB_MEDIA_STREAM_ROOT, '/') . $path);
|
||||
if ($root === false || $fullPath === false || !str_starts_with($fullPath, $root . DIRECTORY_SEPARATOR) || !is_file($fullPath)) {
|
||||
failMediaStream(404, '视频文件不存在');
|
||||
}
|
||||
|
||||
$size = (int)filesize($fullPath);
|
||||
$mime = (string)(mime_content_type($fullPath) ?: 'video/mp4');
|
||||
if (!str_starts_with($mime, 'video/')) {
|
||||
$extension = strtolower((string)pathinfo($fullPath, PATHINFO_EXTENSION));
|
||||
$mime = $extension === 'webm' ? 'video/webm' : ($extension === 'mov' ? 'video/quicktime' : 'video/mp4');
|
||||
}
|
||||
|
||||
$start = 0;
|
||||
$end = max(0, $size - 1);
|
||||
$range = trim((string)($_SERVER['HTTP_RANGE'] ?? ''));
|
||||
if ($range !== '' && preg_match('/^bytes=(\d*)-(\d*)$/', $range, $matches)) {
|
||||
if ($matches[1] !== '') $start = (int)$matches[1];
|
||||
if ($matches[2] !== '') $end = min($end, (int)$matches[2]);
|
||||
if ($start < 0 || $start > $end || $start >= $size) {
|
||||
header('Content-Range: bytes */' . $size);
|
||||
failMediaStream(416, '请求范围无效');
|
||||
}
|
||||
http_response_code(206);
|
||||
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size);
|
||||
}
|
||||
|
||||
$length = $end - $start + 1;
|
||||
header('Content-Type: ' . $mime);
|
||||
header('Content-Length: ' . $length);
|
||||
header('Accept-Ranges: bytes');
|
||||
header('Content-Disposition: inline');
|
||||
header('Cache-Control: public, max-age=86400');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
$stream = fopen($fullPath, 'rb');
|
||||
if ($stream === false) failMediaStream(500, '视频文件无法读取');
|
||||
fseek($stream, $start);
|
||||
$remaining = $length;
|
||||
while ($remaining > 0 && !feof($stream)) {
|
||||
$chunk = fread($stream, min(1024 * 1024, $remaining));
|
||||
if ($chunk === false || $chunk === '') break;
|
||||
echo $chunk;
|
||||
$remaining -= strlen($chunk);
|
||||
flush();
|
||||
}
|
||||
fclose($stream);
|
||||
Reference in New Issue
Block a user