lh hai 1 mes
pai
achega
1de5033ada
Modificáronse 1 ficheiros con 20 adicións e 183 borrados
  1. 20 183
      app/Libs/Helpers.php

+ 20 - 183
app/Libs/Helpers.php

@@ -4432,16 +4432,6 @@ function mapErrorMessage($errorMessage)
 
 /**
  * 将480p视频升级到720p
- * 
- * 重要说明:
- * 从480p到720p的简单放大无法从根本上提升画质,因为原始像素信息有限。
- * 当前方案已经使用了FFmpeg的最佳参数,但仍然无法创造原本不存在的细节。
- 
- * 当前FFmpeg方案的局限性:
- * - 只能做到"尽可能好的放大",无法增加真实细节
- * - 锐化和滤镜只能增强现有细节,不能创造新细节
- * - 最终画质取决于原始480p视频的质量
- * 
  * 使用FFmpeg保持宽高比和画质尽量不丢失
  * 
  * @param string $videoUrl 视频URL地址
@@ -4494,178 +4484,26 @@ function upgrade480pTo720p($videoUrl, $prefix = 'videos')
             'size_mb' => round($inputFileSize / 1024 / 1024, 2) . 'MB'
         ]);
 
-        // 获取原视频的宽高信息
-        $ffprobePath = env('FFPROBE_PATH', 'ffprobe');
-        $probeCmd = "$ffprobePath -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 \"$inputFile\"";
-        $dimensionOutput = trim(shell_exec($probeCmd));
-        
-        if (!$dimensionOutput || strpos($dimensionOutput, 'x') === false) {
-            dLog('video_upgrade')->error('无法获取视频分辨率', ['file' => $inputFile]);
-            @unlink($inputFile);
-            return $videoUrl;
-        }
-        
-        list($origWidth, $origHeight) = explode('x', $dimensionOutput);
-        $origWidth = (int)$origWidth;
-        $origHeight = (int)$origHeight;
-        $origAspectRatio = $origWidth / $origHeight;
-        
-        dLog('video_upgrade')->info('原视频分辨率', [
-            'width' => $origWidth,
-            'height' => $origHeight,
-            'aspect_ratio' => round($origAspectRatio, 4)
-        ]);
-        
-        // 判断视频是横屏还是竖屏
-        // 横屏(16:9): 宽高比 > 1, 目标分辨率 1280*720
-        // 竖屏(9:16): 宽高比 < 1, 目标分辨率 720*1280
-        
-        if ($origAspectRatio > 1) {
-            // 横屏视频 - 目标分辨率1280*720
-            $targetAspectRatio = 16 / 9; // 1280/720 ≈ 1.7778
-            
-            if (abs($origAspectRatio - $targetAspectRatio) < 0.01) {
-                // 原视频宽高比接近16:9,直接缩放到1280*720
-                $targetWidth = 1280;
-                $targetHeight = 720;
-            } else {
-                // 根据原视频宽高比,保持比例缩放
-                // 以较长边(高度720)为基准
-                $targetHeight = 720;
-                $targetWidth = (int)round($targetHeight * $origAspectRatio);
-                // 确保是偶数
-                if ($targetWidth % 2 != 0) $targetWidth += 1;
-                
-                // 如果计算出的宽度超过1280,则以宽度为基准重新计算
-                if ($targetWidth > 1280) {
-                    $targetWidth = 1280;
-                    $targetHeight = (int)round($targetWidth / $origAspectRatio);
-                    if ($targetHeight % 2 != 0) $targetHeight += 1;
-                }
-            }
-        } else {
-            // 竖屏视频 - 目标分辨率720*1280
-            $targetAspectRatio = 9 / 16; // 720/1280 = 0.5625
-            
-            if (abs($origAspectRatio - $targetAspectRatio) < 0.01) {
-                // 原视频宽高比接近9:16,直接缩放到720*1280
-                $targetWidth = 720;
-                $targetHeight = 1280;
-            } else {
-                // 根据原视频宽高比,保持比例缩放
-                // 以较长边(高度1280)为基准
-                $targetHeight = 1280;
-                $targetWidth = (int)round($targetHeight * $origAspectRatio);
-                // 确保是偶数
-                if ($targetWidth % 2 != 0) $targetWidth += 1;
-                
-                // 如果计算出的宽度超过720,则以宽度为基准重新计算
-                if ($targetWidth > 720) {
-                    $targetWidth = 720;
-                    $targetHeight = (int)round($targetWidth / $origAspectRatio);
-                    if ($targetHeight % 2 != 0) $targetHeight += 1;
-                }
-            }
-        }
-        
-        dLog('video_upgrade')->info('目标分辨率', [
-            'width' => $targetWidth,
-            'height' => $targetHeight,
-            'aspect_ratio' => round($targetWidth / $targetHeight, 4),
-            'orientation' => $origAspectRatio > 1 ? 'landscape' : 'portrait'
-        ]);
-
-        // 使用FFmpeg进行视频升级
-        // 方案说明:
-        // 从480p到720p的简单放大无法从根本上提升画质,因为原始信息量有限
-        // 以下是几种可选方案:
-        
-        // 【方案1】超采样+多重滤镜(当前方案,适合快速处理)
-        // 优点: 速度较快,兼容性好
-        // 缺点: 画质提升有限,无法创造原本不存在的细节
-        
-        // 【方案2】Real-ESRGAN AI超分辨率(推荐,需要额外部署)
-        // 使用AI模型进行超分辨率,可以真实提升画质
-        // 需要部署: https://github.com/xinntao/Real-ESRGAN
-        // 命令示例: realesrgan-ncnn-vulkan -i input.mp4 -o output.mp4 -s 1.5
-        
-        // 【方案3】使用FFmpeg的SR滤镜(需要编译支持)
-        // FFmpeg 4.4+ 支持DNN超分辨率
-        // 需要OpenVINO或TensorFlow支持
-        
-        // 当前使用方案1进行处理,如需更好画质,建议:
-        // 1. 直接生成720p视频,而不是升级480p
-        // 2. 或部署Real-ESRGAN等AI超分辨率服务
-        
-        // 优化的FFmpeg参数(已尽可能提升质量)
-        // 滤镜链:
-        // 1. scale: 先放大到2倍,使用超采样
-        // 2. scale: 再缩放到目标分辨率,使用Lanczos算法
-        // 3. eq: 轻微增强对比度和饱和度
-        // 4. unsharp: 锐化增强细节
-        // 5. hqdn3d: 降噪
-        // 6. cas: AMD的对比度自适应锐化(如FFmpeg支持)
-        
+        // 使用FFmpeg将视频升级到720p,使用高质量的Lanczos算法和锐化滤镜
+        // 滤镜说明:
+        // 1. scale=-2:720:flags=lanczos: 使用Lanczos算法缩放,保持宽高比,高度720,宽度自动计算(-2确保是偶数)
+        // 2. unsharp=5:5:1.0:5:5:0.5: 锐化滤镜,增强细节
+        //    - 5:5:1.0 表示亮度锐化(luma_msize_x:luma_msize_y:luma_amount)
+        //    - 5:5:0.5 表示色度锐化(chroma_msize_x:chroma_msize_y:chroma_amount)
+        // 3. hqdn3d=1.5:1.5:6:6: 降噪滤镜,轻微降噪以改善画质
+        //    - 参数分别为亮度空间/时间和色度空间/时间
+        // 编码参数:
+        // -c:v libx264: 使用H.264编码器
+        // -preset veryslow: 使用最慢的编码速度以获得最佳画质(适合对画质要求高的场景)
+        // -crf 16: 恒定质量模式,16表示极高质量(0-51,数值越小画质越好,18是高质量,16是极高质量)
+        // -tune film: 针对电影内容优化(适合AI生成的动画视频)
+        // -profile:v high: 使用H.264 High Profile,支持更高级的压缩特性
+        // -level 4.1: H.264 level 4.1,支持更高的码率和分辨率
+        // -pix_fmt yuv420p: 像素格式,确保兼容性
+        // -c:a copy: 音频直接复制,不重新编码
+        // -movflags +faststart: 优化网络播放
         $ffmpegPath = env('FFMPEG_PATH', 'ffmpeg');
-        
-        // 检查FFmpeg是否支持cas滤镜
-        $checkCasCmd = "$ffmpegPath -filters 2>&1 | grep -i \"cas\"";
-        $hasCas = !empty(shell_exec($checkCasCmd));
-        
-        // 构建滤镜链
-        $filterChain = [];
-        
-        // 1. 先进行超采样放大(放大到目标尺寸的1.2倍)
-        $superWidth = (int)($targetWidth * 1.2);
-        $superHeight = (int)($targetHeight * 1.2);
-        if ($superWidth % 2 != 0) $superWidth += 1;
-        if ($superHeight % 2 != 0) $superHeight += 1;
-        $filterChain[] = "scale={$superWidth}:{$superHeight}:flags=lanczos";
-        
-        // 2. 轻微增强对比度和饱和度
-        $filterChain[] = "eq=contrast=1.05:saturation=1.05:brightness=0.02";
-        
-        // 3. 锐化
-        $filterChain[] = "unsharp=7:7:1.5:7:7:0.8";
-        
-        // 4. 降噪
-        $filterChain[] = "hqdn3d=1.0:1.0:4:4";
-        
-        // 5. 再次缩放到目标分辨率
-        $filterChain[] = "scale={$targetWidth}:{$targetHeight}:flags=lanczos";
-        
-        // 6. 如果支持cas,添加对比度自适应锐化
-        if ($hasCas) {
-            $filterChain[] = "cas=0.5";
-        }
-        
-        // 7. 最后再次轻微锐化
-        $filterChain[] = "unsharp=5:5:0.8:5:5:0.4";
-        
-        $vfFilter = implode(',', $filterChain);
-        
-        // 编码参数优化
-        // -c:v libx264: H.264编码
-        // -preset slow: 慢速编码(veryslow太慢,slow是较好的平衡点)
-        // -crf 15: 极高质量(15比16更高,接近无损)
-        // -tune film: 针对电影内容
-        // -profile:v high: High Profile
-        // -level 4.2: 支持更高分辨率和码率
-        // -pix_fmt yuv420p: 标准像素格式
-        // -x264-params: 额外的x264参数
-        //   - aq-mode=3: 自适应量化模式3(最佳)
-        //   - aq-strength=0.8: 自适应量化强度
-        //   - deblock=-1,-1: 轻微减少去块滤波(保留更多细节)
-        //   - ref=5: 参考帧数量
-        //   - me=umh: 运动估计算法(高质量)
-        //   - subme=10: 子像素运动估计(最高)
-        //   - psy-rd=1.0,0.15: 心理视觉优化
-        // -c:a copy: 音频复制
-        // -movflags +faststart: 快速启动
-        
-        $x264Params = "aq-mode=3:aq-strength=0.8:deblock=-1,-1:ref=5:me=umh:subme=10:psy-rd=1.0,0.15";
-        
-        $ffmpegCmd = "$ffmpegPath -i \"$inputFile\" -vf \"$vfFilter\" -c:v libx264 -preset slow -crf 15 -tune film -profile:v high -level 4.2 -pix_fmt yuv420p -x264-params \"$x264Params\" -c:a copy -movflags +faststart -y \"$outputFile\" 2>&1";
+        $ffmpegCmd = "$ffmpegPath -i \"$inputFile\" -vf \"scale=-2:720:flags=lanczos,unsharp=5:5:1.0:5:5:0.5,hqdn3d=1.5:1.5:6:6\" -c:v libx264 -preset veryslow -crf 16 -tune film -profile:v high -level 4.1 -pix_fmt yuv420p -c:a copy -movflags +faststart -y \"$outputFile\" 2>&1";
         
         dLog('video_upgrade')->info('开始升级视频到720p', ['command' => $ffmpegCmd]);
         $output = shell_exec($ffmpegCmd);
@@ -4687,8 +4525,7 @@ function upgrade480pTo720p($videoUrl, $prefix = 'videos')
         dLog('video_upgrade')->info('视频升级成功', [
             'input_size' => round($inputFileSize / 1024 / 1024, 2) . 'MB',
             'output_size' => round($outputFileSize / 1024 / 1024, 2) . 'MB',
-            'size_ratio' => $sizeRatio,
-            'target_resolution' => "{$targetWidth}x{$targetHeight}"
+            'size_ratio' => $sizeRatio
         ]);
 
         // 上传到TOS - 使用普通的文件名,不暴露是升级后的视频