近期在springboot项目中需要做一个视频加水印的功能,期初是通过FFMPEG的方式完成对视频加水印,在实际使用中发现比较消耗CPU,后面借助七牛云接口(参考:视频水印(avwatermark)_API 文档_智能多媒体服务 - 七牛开发者中心 )平台完成,现把自己的代码贴上,仅供参考!
//--------七牛云参数配置类-------------------------
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.StringJoiner;
@Component
@ConfigurationProperties(prefix = "qiniu")
@Data
public class QiniuConfig {
public String accessKey;
public String secretKey;
public String bucket;
//七牛云返回的图片域名地址
public String mediaurl;
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getBucket() {
return bucket;
}
public void setBucket(String bucket) {
this.bucket = bucket;
}
public String getMediaurl() {
return mediaurl;
}
public void setMediaurl(String mediaurl) {
this.mediaurl = mediaurl;
}
@Override
public String toString() {
return new StringJoiner(", ", QiniuConfig.class.getSimpleName() + "[", "]")
.add("accessKey='" + accessKey + "'")
.add("secretKey='" + secretKey + "'")
.add("bucket='" + bucket + "'")
.add("MediaUrl='" + mediaurl + "'")
.toString();
}
}
备注:在yml中配置七牛云的参数
qiniu:
accessKey: xxx #accessKey
secretKey: yyyy #secretKey
bucket: sss #七牛云添加的应用空间名
mediaurl: https://qiniu.xx.cn/ #七牛云存储文件域名地址
//--------QiniuUtils 工具类-------------------------
import com.alibaba.fastjson.JSONObject;
import com.qiniu.cdn.CdnManager;
import com.qiniu.cdn.CdnResult;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.processing.OperationManager;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import com.qiniu.util.UrlSafeBase64;
import com.ymkj.common.utils.http.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* @Description: 七牛 工具类
* @Author: wyc
*/
@Component
public class QiniuUtils {
@Autowired
private QiniuConfig qiniuConfig;
//设置转码的队列 参考:https://developer.qiniu.com/dora/kb/3853/how-to-create-audio-and-video-processing-private-queues
private static final String PIPE_LINE = "在七牛云上添加的转码序列";
/**
* @Description: 七牛云接口--视频加水印功能
* @Param videoKey:上传到七牛云服务器的文件名称 如:test/test/mp4D83178ED-DFFA-4878-A809-367A0626C2EC.mp4
* logoUrl:按照视频分辨率生成的水印图片,存在了七牛云服务器(完整的文件地址,如:https://qiniu.xx.cn/logo.png)
* @Author: wyc
* @date:2022/2/7 17:07
*/
public String waterMarkByQiniu(String videoKey, String logoUrl) {
Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
//新建一个OperationManager对象
OperationManager operater = new OperationManager(auth, cfg);
//水印文件
String pictureurl = UrlSafeBase64.encodeToString(logoUrl);
//设置转码操作参数
String fops = "avthumb/mp4/wmImage/" + pictureurl;
//加水印后的文件自定义名称
String saveAsName = "videosDownLoad/" + UUID.randomUUID().toString().replaceAll("-", "") + ".mp4";
//可以对转码后的文件进行使用saveas参数自定义命名,当然也可以不指定文件会默认命名并保存在当前空间。
String urlbase64 = UrlSafeBase64.encodeToString(qiniuConfig.getBucket() + ":" + saveAsName);
//saveas:转码加水印后另存为文件名 urlbase64
String pfops = fops + "|saveas/" + urlbase64;
//设置pipeline参数
StringMap params = new StringMap().putWhen("force", 1, true).putNotEmpty("pipeline", PIPE_LINE);
try {
String persistid = operater.pfop(qiniuConfig.getBucket(), videoKey, pfops, params);
String code = getCode(persistid);
if (code.equals("0")) {
return qiniuConfig.getMediaurl() + saveAsName;
}
} catch (QiniuException e) {
//捕获异常信息
Response r = e.response;
// 请求失败时简单状态信息
System.out.println(r.toString());
e.printStackTrace();
}
return null;
}
/**
* @Description:递归实现--直到返回code==0 (状态码 0成功 , 1等待处理 , 2正在处理 , 3处理失败)
* @Author: wyc
* @Param:[persistid]
* @return:java.lang.String
*/
public static String getCode(String persistid) {
//打印返回的persistid
String json = HttpUtils.sendGet("http://api.qiniu.com/status/get/prefop", "id=" + persistid);
JSONObject obj = JSONObject.parseObject(json);
String code = obj.getString("code");
if (code.equals("0")) {
return code;
}
return getCode(persistid);
}
/**
* 上传本地文件到七牛云
*
* @param filePath 文件本地路径
* @param folderName 上传七牛云后的文件夹名
* @param fileType 上传的文件的后缀名
*/
public String uploadFileToQiniu(String filePath, String folderName, String fileType) {
/**指定保存到七牛的文件名--同名上传会报错 {"error":"file exists"}*/
/** {"hash":"FrQF5eX_kNsNKwgGNeJ4TbBA0Xzr","key":"members/imges/054cbfd6-b375-4dd8-865c-d955c3e852c0"} 正常返回 key为七牛空间地址 http:/xxxx.com/aa1.jpg */
try {
//调用put方法上传
UploadManager uploadManager = new UploadManager(new Configuration());
//返回体:res.bodyString()
Response res = uploadManager.put(filePath, folderName + (UUID.randomUUID() + "." + fileType), getUpToken());
//打印返回的信息
if (res.statusCode == 200) {
//200为上传成功
JSONObject obj = JSONObject.parseObject(res.bodyString());
return obj.getString("key");
}
} catch (QiniuException e) {
Response r = e.response;
e.printStackTrace();
}
return null;
}
/**
* 删除七牛云服务器上的文件
*
* @param filePath 七牛云返回的文件的详细路径
* @return
* @throws QiniuException
*/
public String deleteFileFromQiniu(String filePath) throws QiniuException {
String fileName = filePath.replaceAll(qiniuConfig.getMediaurl(), "");
//设置华东的服务器
Configuration cfg = new Configuration(Zone.autoZone());
Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
BucketManager bucketManager = new BucketManager(auth, cfg);
Response res = bucketManager.delete(qiniuConfig.getBucket(), fileName);
//返回200表示删除成功
String returCode = res.statusCode + "";
if (returCode.equals("200")) {
//刷新
refresh(filePath);
}
return returCode;
}
/**
* 刷新文件
*
* @param url 七牛云返回的完整的图片路径
* 例如:http://img.1mei.vip/0244f5e3-b4ff-4017-a2e7-efc2cd725c4f
* @throws QiniuException
*/
public void refresh(String url) throws QiniuException {
String[] urls = {url};
Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
CdnManager c = new CdnManager(auth);
CdnResult.RefreshResult response = c.refreshUrls(urls);
System.out.println(response);
}
public String getUpToken() {
Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
return auth.uploadToken(qiniuConfig.getBucket());
}
//测试
public static void main(String[] args) {
//上传本地文件
String filePath = "C:\\Users\\Administrator\\Pictures\\Camera Roll\\3.jpg";
//上传后会生成相应的文件夹
String folderName = "members/imges/";
//自定义后缀名,自己看着舒服
String type = filePath.indexOf(".") != -1 ? filePath.substring(filePath.lastIndexOf(".") + 1, filePath.length()) : null;
//1>,上传图片 上传后返回相应文件名key
String imgKey = new QiniuUtils().uploadFileToQiniu(filePath, folderName, type);
filePath = "C:\\Users\\Administrator\\Pictures\\Camera Roll\\视频文件.mp4";
folderName = "members/videos/";
type = filePath.indexOf(".") != -1 ? filePath.substring(filePath.lastIndexOf(".") + 1, filePath.length()) : null;
System.out.println(type);
//2>,上传视频
String videoKey = new QiniuUtils().uploadFileToQiniu(filePath, folderName, type);
//七牛云加水印 res即加水印后返回的文件完整url
String res = new QiniuUtils().waterMarkByQiniu(videoKey, "https://qiniu.xx.cn/" + imgKey );
}
}
(备注:测试方法中同时提供了上传的操作,因本人的需求是按照不同视频的分辨率生成了不同大小的水印,所以在实际开发中,要同时优先把视频原文件以及生成的水印先上传到七牛云,最后再通过waterMarkByQiniu(videoKey, "https://qiniu.xx.cn/" + imgKey )完成加水印的全过程。)