序言
这个是从抖音上学来的,一开始刷抖音,遇到不少字符串跳舞的视频,因此来实践一下
主要分为三个部分
- 静态图片转静态图片
- gif转gif
- 视频转视频
视频转视频
主要用到了FFmpeg这个工具,利用命令对视频文件进行操作。首先根据自己调的参数进行图片的截取(本文的是1秒10帧的参数),图片转换,然后分离音频,最后字符图片和音频合成目标视频。
FFmpeg的代码库:
https://github.com/FFmpeg/FFmpeg
FFmpeg下载地址:
https://ffmpeg.org/download.html
本位使用的版本:
https://blog-lossingdawn.oss-cn-shanghai.aliyuncs.com/img2text/ffmpeg-20180201-b1af0e2-win64-static.zip
效果如下
没做细致的调整,视频的转换可以调调参数

测试代码
1 2 3 4 5 6 7 8
| @Test public static void videoTest() { String srcVideoPath = "F:/123/123.mp4"; String tarImagePath = "F:/123/mp/"; String tarAudioPath = "F:/123/mp/audio.aac"; String tarVideoPath = "F:/123/1234.mp4"; VideoUtil.readVideo(srcVideoPath,tarImagePath,tarAudioPath,tarVideoPath); }
|
代码如下
主要用到的几个命令,其他按帧截图命令参考文末链接4:
1 2 3 4 5 6
| // 截图 ffmpeg -ss 10 -i input.flv -y -f image2 -vframes 100 -s 352x240 b-%03d.jpg // 分离音频 ffmpeg -i 3.mp4 -vn -y -acodec copy 3.aac // 合成视频 ffmpeg -threads2 -y -r 10 -i /tmpdir/image%04d.jpg -i audio.mp3 -absf aac_adtstoasc output.mp4
|
环境:
JDK 1.8
完整代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
public static boolean processFfmpegImage(String srcVideoPath, String tarImagePath, int width, int hight, float offsetValue, float vframes) { if (!checkfile(srcVideoPath)) { System.out.println("【" + srcVideoPath + "】 不存在 !"); return false; } List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-i");
commend.add(srcVideoPath);
commend.add("-y");
commend.add("-f");
commend.add("image2");
commend.add("-ss");
commend.add(offsetValue + "");
commend.add("-t");
commend.add(vframes + "");
commend.add("-s");
commend.add(width + "x" + hight);
commend.add(tarImagePath);
try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); builder.redirectErrorStream(true); Process process = builder.start(); doWaitFor(process); process.destroy(); if (!checkfile(tarImagePath)) { System.out.println(tarImagePath + " is not exit! processFfmpegImage 转换不成功 !"); return false; } return true; } catch (Exception e) { e.printStackTrace(); System.out.println("【" + srcVideoPath + "】 processFfmpegImage 转换不成功 !"); return false; } } public static boolean processFfmpegAudio(String srcVideoPath, String tarAudioPath) { if (!checkfile(srcVideoPath)) { System.out.println("【" + srcVideoPath + "】 不存在 !"); return false; } List<String> commend = new java.util.ArrayList<String>(); commend.add(ffmpegPath); commend.add("-i"); commend.add(srcVideoPath); commend.add("-vn");
commend.add("-y"); commend.add("-acodec"); commend.add("copy"); commend.add(tarAudioPath); try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); builder.redirectErrorStream(true); Process process = builder.start(); doWaitFor(process); process.destroy(); if (!checkfile(tarAudioPath)) { System.out.println(tarAudioPath + " is not exit! processFfmpegAudio 转换不成功 !"); return false; } return true; } catch (Exception e) { e.printStackTrace(); System.out.println("【" + srcVideoPath + "】 processFfmpegAudio 转换不成功 !"); return false; } }
public static boolean processFfmpegVideo(String imagePath, String audioPath, String tarVideoPath, int step) {
List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-threads"); commend.add("2");
commend.add("-y");
commend.add("-r");
commend.add(step + "");
commend.add("-i");
commend.add(imagePath);
commend.add("-i");
commend.add(audioPath);
commend.add("-absf");
commend.add("aac_adtstoasc");
commend.add(tarVideoPath);
try { ProcessBuilder builder = new ProcessBuilder(); builder.command(commend); builder.redirectErrorStream(true); builder.redirectOutput(new File("F:/123/log/log.log")); Process process = builder.start(); doWaitFor(process); process.destroy(); if (!checkfile(tarVideoPath)) { System.out.println(tarVideoPath + " is not exit! processFfmpegVideo 转换不成功 !"); return false; } return true; } catch (Exception e) { e.printStackTrace(); System.out.println("【" + tarVideoPath + "】 processFfmpegVideo 转换不成功 !"); return false; } }
|
源码地址:
https://github.com/Ruffianjiang/java4fun/tree/master/img2text
参考:
- https://blog.csdn.net/i_likechard/article/details/79032931
- https://blog.csdn.net/xiaocao9903/article/details/53420519
- https://blog.csdn.net/wangshuainan/article/details/77914508?fps=1&locationNum=4
- https://blog.csdn.net/yourijing/article/details/50786758