PHP-FFMpeg视频水印

75 阅读2分钟

原因:

最近产品经理跟我反应说,鱼粉圈被同行偷素材拿去用,我知乎好家伙,真的全靠同行衬托,偷素材这决不能忍,为了保护版权,是时候放大招了 ,视频水印安排上

aefa46bf8da484bf3f2cf6d7bfd4620b.gif

准备工作

视频服务器操作哪家强,还得山东走蓝翔。。。。额,跑题了,还得是FFMpeg

开始安装,由于我的服务器系统是centos7所以后面的步骤都是centos的命令,其他linux系统的仅做参考

1.yum镜像源问题要更新一下,防止拉取失败

没有yum拉取失败是这样的

image.png

执行更新yum镜像源命令

curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

其他版本可参考

developer.aliyun.com/mirror/cent…

2.安装FFMpeg

2.1这个源安装的ffmpeg版本是3.4(为啥装这个?主要是3.4以前有未实验acc报错)

yum install epel-release yum install -y https://mirrors.ustc.edu.cn/rpmfusion/free/el/rpmfusion-free-release-7.noarch.rpm

2.2然后安装

yum install -y ffmpeg ffmpeg-devel

2.3 安装成功后查看版本

ffmpeg -version

image.png

3.安装PHP-FFMpeg

github仓库:(github.com/PHP-FFMpeg/…)

我用的是tp6所以直接composer安装

composer require php-ffmpeg/php-ffmpeg

安装成功后,装逼时刻到了

dedd2aa289636c66a2f0c2d2cd643850.gif

4.小试身手

image.png 以下是php代码(注意水印图片建议是PNG就是透明底)


use FFMpeg\FFMpeg;
use FFMpeg\FFProbe;
use FFMpeg\Format\Video\X264;

class LocalVideo{
    
    //视频水印
    /** 建议路径使用绝对路径
     * @param $videoPath 原视频路径
     * @param $outputPath 水印视频生成路径
     * @param $watermarkImagePath 水印logo
     * @return bool
     */
    public function addWatermarkWithPHPFFMpeg($videoPath, $outputPath, $watermarkImagePath)
    {
        $ffmpeg = FFMpeg::create([
            'ffmpeg.binaries' => '/usr/bin/ffmpeg',  // 或者其他FFmpeg实际路径
            'ffprobe.binaries' => '/usr/bin/ffprobe', // 或者其他ffprobe实际路径
        ]);
        $video = $ffmpeg->open($videoPath);
        $video->filters()->watermark($watermarkImagePath, [
                'position' => 'relative',
                'top' => 10,
                'left' => 10,
            ])->watermark($watermarkImagePath, array(
                'position' => 'relative',
                'bottom' => 20,
                'right' => 20,
            ));
        $video ->save(new X264(), $outputPath);
        // 可以在这里添加错误处理
        return true;
    }
}

执行后,得出以下水印视频

image.png

5.庖丁解牛,是时候装逼了

533b2d1ba0cbb22fc1e255e004717513.gif

代码走起


use FFMpeg\FFMpeg;
use FFMpeg\FFProbe;
use FFMpeg\Format\Video\X264;

class LocalVideo{
    
    //视频水印
    /** 建议路径使用绝对路径
     * @param $videoPath 原视频路径
     * @param $outputPath 水印视频生成路径
     * @param $watermarkImagePath 水印logo
     * @return bool
     */
    public function addWatermarkWithPHPFFMpeg($videoPath, $outputPath, $watermarkImagePath)
    {
        $ffmpeg = FFMpeg::create([
            'ffmpeg.binaries' => '/usr/bin/ffmpeg',  // 或者其他FFmpeg实际路径
            'ffprobe.binaries' => '/usr/bin/ffprobe', // 或者其他ffprobe实际路径
            'timeout'          => 3600, // The timeout for the underlying process
            'ffmpeg.threads'   => 12,
        ]);
        $ffprobe = FFProbe::create([
            'ffmpeg.binaries' => '/usr/bin/ffmpeg',  // 或者其他FFmpeg实际路径
            'ffprobe.binaries' => '/usr/bin/ffprobe', // 或者其他ffprobe实际路径
        ]);
        $format = $ffprobe->streams($videoPath) // extracts streams informations
        ->videos()                      // filters video streams
        ->first();
        // 获取视频宽高
        $width = $format->get('width');
        $height = $format->get('height');
        $video = $ffmpeg->open($videoPath);
            if($width>0 && $height>0){
            // 给原图左上角添加水印并保存water_image.png
            for ($i=1;$i<=$width;$i+=200){
                for ($j=1;$j<$height;$j+=200){
                    $video->filters()->watermark($watermarkImagePath, [
                        'position' => 'absolute',
                        'x' =>$i,
                        'y' => $j,
                    ]);
                }
            }
        }
        $video ->save(new X264(), $outputPath);
        // 可以在这里添加错误处理
        return true;
    }
}

image.png

至此收官了,虽然还有一些不完美的地方,就是如果你视频使用的是AV1,那么恭喜你,要起飞了,我也在研究中