为自己的短视频盖一个专属的印章----JavaCV之流媒体水印

简介: 为自己的短视频盖一个专属的印章----JavaCV之流媒体水印

无论是歌曲,小说,还是技术文章从古至今都是各种抄袭,各种拿来就用,随着技术的发展,朋友圈的图片,商铺的图片,也开始各种拿来就用,所以发明了水印,当然不止图片有水印,视频也可以有的。

这期我们介绍的是添加静态文字水印,当然可以添加图片水印,动态文字水印,只是这期的重点是添加静态文字水印。添加静态文字水印有两种方法。

不论怎么样,都要引入 Maven

<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform -->
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.2</version>
</dependency>

第一种(使用 FFmpeg 原生的)

FFmpegFrameFilter (过滤器)

FFmpegFrameFilter 功能很强大,这个类一共有三个构造方法。

第一个

//过滤音频,给音频做一些处理
public FFmpegFrameFilter(String afilters, int audioChannels)

第二个

//过滤视频,给视频做一些处理
public FFmpegFrameFilter(String filters, int imageWidth, int imageHeight)

第三个

//同时过滤音频与视频,给音视频做一些处理
public FFmpegFrameFilter(String videoFilters, String audioFilters, int imageWidth, int imageHeight, int audioChannels)

videoFilters 这个是视频的一些处理设置,具体参考 ffmpeg.audioFilters 这个是音频的一些处理设置,具体参考 ffmpeg.imageWidth imageHeight这个是视频的宽和高。audioChannels 这个是音频的通道。

都说清楚了,那我们上代码吧。

常量代码

//设置修改视频的路径
public static final String VIDEO_OLD_PATH =
        "/voicedemo/src/main/java/xin/zhuyao/voicedemo/video/1608599180608-0.mp4";
//设置新生产视频的路径
public static final String VIDEO_NEW_PATH =
        "/voicedemo/src/main/java/xin/zhuyao/voicedemo/test/1608599180608-1.mp4";
//字体
private static final String FONT_PATH =
        "/Library/Fonts/Arial\\ Unicode.ttf";

核心代码

/**
    * 添加字体水印
    * @param content 水印内容
    * @throws Exception Exception
    */
public static void addTextByFFmpegFrame(String content) throws Exception {

        //抓取器
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(VIDEO_OLD_PATH);
        //打开抓取器
        grabber.start();

        //录播器
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(
                VIDEO_NEW_PATH,
                grabber.getImageWidth(),
                grabber.getImageHeight(),
                grabber.getAudioChannels());

        // 视频相关配置,取原视频配置
        recorder.setFrameRate(grabber.getFrameRate());
        recorder.setVideoCodec(grabber.getVideoCodec());
        recorder.setVideoBitrate(grabber.getVideoBitrate());

        // 音频相关配置,取原音频配置
        recorder.setSampleRate(grabber.getSampleRate());
        recorder.setAudioCodec(grabber.getAudioCodec());
        recorder.setAudioBitrate(grabber.getAudioBitrate());
        //开启录播器
        recorder.start();

        //过滤器
        String filterContent = "drawtext=fontfile="+ FONT_PATH + ": text='" + content + "': fontsize=h/30: x=(w-text_w)/2: y=(h-text_h*2)";
        FFmpegFrameFilter fFmpegFrameFilter = new FFmpegFrameFilter(
                filterContent,
                grabber.getImageWidth(),
                grabber.getImageHeight());
        //开启视频过滤器
        fFmpegFrameFilter.start();

        Frame frame;
        while ((frame = grabber.grab()) != null) {
            if (frame.image != null) {
                fFmpegFrameFilter.push(frame);
                recorder.record(fFmpegFrameFilter.pullImage());
            }
        }
    fFmpegFrameFilter.close();
    recorder.close();
    grabber.close();
}

测试

public static void main(String[] args) throws Exception {
    addTextByFFmpegFrame("程序员小朱");
}

第二种(我取每一帧,然后把文字加在每一帧上)

这个逻辑很清楚吧,就是视频里取每一帧图片,然后添加上文字在放上去。

常量代码

//设置修改视频的路径
public static final String VIDEO_OLD_PATH =
        "/voicedemo/src/main/java/xin/zhuyao/voicedemo/video/1608599180608-0.mp4";
//设置新生产视频的路径
public static final String VIDEO_NEW_PATH =
        "/voicedemo/src/main/java/xin/zhuyao/voicedemo/test/1608599180608-1.mp4";
//字体
private static final String FONT_PATH =
        "/Library/Fonts/Arial\\ Unicode.ttf";

核心代码

public static void addTextByGraphics(String context) throws Exception {
    // 设置源视频、加字幕后的视频文件路径
    FFmpegFrameGrabber grabber =
            new FFmpegFrameGrabber(VIDEO_OLD_PATH);
    grabber.start();
    FFmpegFrameRecorder recorder =
            new FFmpegFrameRecorder(VIDEO_NEW_PATH,
                    grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());

    // 视频相关配置,取原视频配置
    recorder.setFrameRate(grabber.getFrameRate());
    recorder.setVideoCodec(grabber.getVideoCodec());
    recorder.setVideoBitrate(grabber.getVideoBitrate());

    // 音频相关配置,取原音频配置
    recorder.setSampleRate(grabber.getSampleRate());
    recorder.setAudioCodec(grabber.getAudioCodec());
    recorder.setAudioBitrate(grabber.getAudioBitrate());
    recorder.start();

    Java2DFrameConverter converter = new Java2DFrameConverter();

    Frame frame;
    while ((frame =grabber.grab()) != null) {
        // 从视频帧中获取图片
        if (frame.image != null) {
            BufferedImage bufferedImage = converter.getBufferedImage(frame);
            // 对图片进行文本合入
            bufferedImage = addText(bufferedImage, context);
            // 视频帧赋值,写入输出流
            recorder.record(converter.getFrame(bufferedImage));
        }
        //配置音乐
        if (frame.samples != null) {
            recorder.record(frame);
        }

    }
    recorder.close();
    grabber.close();
}


/**
    * 图片添加文本
    *
    * @param bufImg bufImg
    * @param content content
    * @return BufferedImage
    */
private static BufferedImage addText(BufferedImage bufImg, String content) {
    Graphics2D graphics = bufImg.createGraphics();
    graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));

    //设置图片背景
    graphics.drawImage(bufImg, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);

    //设置字体
    Font font= new Font("宋体", Font.BOLD, 32);
    FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
    graphics.setFont(font);
    int textWidth =metrics.stringWidth(content);
    graphics.drawString(content, (bufImg.getWidth() - textWidth) / 2, bufImg.getHeight() / 2);
    graphics.dispose();
    return bufImg;
}
public static void main(String[] args) throws Exception {
    addTextByGraphics("程序员小朱");
}
相关文章
|
开发工具
语音聊天室源码技术美颜滤镜功能的配置
美颜滤镜功能从现身以来一直受到人们的火爆追捧,所以为了顺应市场的需求,开发语音聊天室源码平台也必须要有美颜滤镜功能,今天我就将语音聊天室源码技术美颜滤镜功能的配置知识分享给大家。
语音聊天室源码技术美颜滤镜功能的配置
防伪彩色二维码的设计制作
彩码指彩色二维码、一般使用QRcode类型,彩码的作用主要是防伪领域
144 0
|
编解码 定位技术 数据库
这个方法教你,下载 50 年前自己家乡的高清卫星照片
这个方法教你,下载 50 年前自己家乡的高清卫星照片
293 0
|
编解码 Android开发 iOS开发
使用APICloud开发app录音功能
mp3Recorder模块封装在iOS、Android下录音直接生成mp3,统一两个平台的录音生成文件,方便双平台之间的交互,减少录音完成后再转码的过程;同时提供分贝波形图显示UI;使用该模块前需要打开麦克风权限。
287 0
|
数据采集 前端开发 开发工具
虎牙小姐姐照片
概述 最近几年由于网络直播的兴起,直播行业也是越来越火,一些老宅男也是比较喜欢看小姐姐,然而许多人却会碰到直播界面图片不会保存的问题,那么接下来我将用十几行代码告诉你如何拿到大量美女图片,拿去做手机壁纸。
391 0
虎牙小姐姐照片
|
容器
短视频平台搭建,相机截取图片位置
短视频平台搭建,相机截取图片位置
532 0
|
JavaScript vr&ar Android开发
24. WebVR播放器: 在豪宅里看电影
#紧接上文 消费升级的必然是体验升级,AR/VR技术是提升用户体验的方式之一。智能手机让用户可以AnyTime、AnyWhere的体验移动生活服务,再结合扁平化UI设计,在小小的手机屏幕上,实现了可以媲美PC的体验,用户已经从开始的惊艳,慢慢变成了适应,认为智能手机就应该是这样子,即我们所说的《审
5508 0
|
数据安全/隐私保护 Python Web App开发
抖音水印python源码
抖音水印python源码 import hashlibimport base64import timeimport requestsimport jsonimport lxml.html def base64encode(text: str, reverse_map: bool = False) ...
1222 0