ffmpeg移动弹幕

bat编写

做出一个初始模型, 使得视频出现弹幕文字

ffplay -i input.mp4 -vf "drawtext=fontsize=20:fontfile=FreeSerif.ttf:text='test':x=w-100*t:y=50"

将这个放入一个bat文件之中

@echo off
setlocal enabledelayedexpansion
rem 获取文件名,不带扩展名
set "barrage='hello'"
rem 执行 ffmpeg 命令
ffplay -i input.mp4 -vf "drawtext=fontsize=20:fontfile=FreeSerif.ttf:text=!barrage!:x=w-100*t:y=1"
endlocal

在固定时间显示文字并移动

ffplay -i input.mp4 -vf "drawtext=fontsize=20:fontfile=FreeSerif.ttf:text='test':x=w-100*(t-10):y=50:enable=gt(t,10)"

如何添加多个文字

ffplay -i input.mp4 -vf "drawtext=fontsize=20:fontfile=FreeSerif.ttf:text='Text1':x=100:y=50:enable=gt(t\,1)*lt(t\,20),drawtext=fontsize=20:fontfile=FreeSerif.ttf:text='Text2':x=100:y=100:enable=gt(t\,3)*lt(t\,40)"

将多个文字和时间整合在一起

ffplay -i input.mp4 -vf "drawtext=fontsize=20:fontfile=FreeSerif.ttf:text='Text1':x=w-100*(t-1):y=50:enable=gt(t\,1)*lt(t\,20),drawtext=fontsize=20:fontfile=FreeSerif.ttf:text='Text2':x=w-100*(t-3):y=100:enable=gt(t\,3)*lt(t\,40)"

使用bat做二层循环

@echo off
setlocal enabledelayedexpansion

set "TEXT_INFO=Text1 10 20 100 50;Text2 30 40 200 100;Text3 60 70 300 150"

rem 遍历每个分号分隔的部分
for %%A in ("%TEXT_INFO:;=";"%") do (
    echo Processing: %%~A

    rem 使用空格分隔每个部分
    for %%B in (%%~A) do (
        echo    %%~B
    )
)

endlocal

结果显示为

Processing: Text1 10 20 100 50
   Text1
   10
   20
   100
   50
Processing: Text2 30 40 200 100
   Text2
   30
   40
   200
   100
Processing: Text3 60 70 300 150
   Text3
   60
   70
   300
   150

但是如果想要对每一个项对应一个变量操作, 可以使用

@echo off
setlocal enabledelayedexpansion

set "TEXT_INFO=Text1 10 20 100 50;Text2 30 40 200 100;Text3 60 70 300 150"

rem 遍历每个分号分隔的部分
for %%A in ("%TEXT_INFO:;=";"%") do (
    echo Processing: %%~A

    rem 使用空格分隔每个部分
    set count=0
    for %%B in (%%~A) do (
        set /a count+=1
        set "ITEM!count!=%%~B"  rem 将每个项赋值给 ITEM1, ITEM2, ...
    )

    rem 输出所有赋值的项
    for /L %%C in (1,1,!count!) do (
        echo    ITEM%%C: !ITEM%%C!
    )
)

endlocal

结果为

Processing: Text1 10 20 100 50
   ITEM1: Text1
   ITEM2: 10
   ITEM3: 20
   ITEM4: 100
   ITEM5: 50
Processing: Text2 30 40 200 100
   ITEM1: Text2
   ITEM2: 30
   ITEM3: 40
   ITEM4: 200
   ITEM5: 100
Processing: Text3 60 70 300 150
   ITEM1: Text3
   ITEM2: 60
   ITEM3: 70
   ITEM4: 300
   ITEM5: 150

通过以上内容,可以得到雏形

@echo off
setlocal enabledelayedexpansion
:: 设置视频文件名
set VIDEO_FILE=hy.mp4
:: 定义文本信息和时间
:: 格式: 文本内容 起始时间 结束时间 X坐标 Y坐标
set "TEXT_INFO=Text1 1 20 10 50;Text2 3 40 20 100;Text3 5 70 50 150"
::x=w-100*(t-10)
:: 初始化 FFmpeg 命令字符串
set FFMPEG_CMD=ffplay -i "%VIDEO_FILE%" -vf "
rem 遍历每个分号分隔的部分
for %%A in ("%TEXT_INFO:;=";"%") do (
    echo Processing: %%~A
    echo "--------------------"
    rem 使用空格分隔每个部分
    set count=0
    for %%B in (%%~A) do (
        set /a count+=1
        set "ITEM!count!=%%~B"  rem 将每个项赋值给 ITEM1, ITEM2, ...
    )
    echo ".................."
    ::!FFMPEG_CMD!
    set "FFMPEG_CMD=!FFMPEG_CMD!drawtext=fontsize=20:fontfile=FreeSerif.ttf:text='!ITEM1!':x=w-100*(t-!ITEM2!):y=!ITEM5!:enable=gt(t\,!ITEM2!),"
    echo !FFMPEG_CMD!

)
:: 移除最后一个逗号并添加结束方括号
set FFMPEG_CMD=!FFMPEG_CMD:~0,-1!"
echo !FFMPEG_CMD!
endlocal

接下来可以将想要放入的弹幕以及格式填入TEXT_INFO中,但是如果弹幕太多, 会显示The input line is too long,那其实我们可以多试几次

@echo off
setlocal enabledelayedexpansion

set VIDEO_FILE=hy.mp4
set "TEXT_INFO=⭐———————— 27 16777215 300 25;我在叙利亚都没受过这么重的伤 107 16776960 270 25;底部淡蓝色字幕菌施工完毕,感谢欣赏 96 8700107 270 25;“升空的烟火,是圆的,还是扁的?”“圆的也好,扁的也好,奇怪形状也罢。只要我们俩在一起,什么我都不在乎。” 35 16646914 30 25;烟花易逝,人情长存 3 16707842 270 25;樱花易逝,春树常绿,以声之色,塑以花之形,将你之名,刻之我心。 75 16777215 270 25;赶快去表白,别留遗憾!!! 55 16646914 30 25;君(きみ)の後(うし)ろ姿(すがた)你留下背影的那天 15 9033215 300 25;焰色反应() 26 16707842 240 25;此时,西片正在找高木 99 15138834 270 25;底部淡蓝色中文字幕君开始施工,并非翻译 7 8700107 240 25;2022中考顺利!加油!! 35 16707842 270 25;↑说句人话:我爱你西宫硝子↑ 38 16776960 180 25;两年了,我已经放下啦 20 16707842 300 25;烟花易逝,人情长存 13 15138834 0 25;烟花易逝,人情长存 91 16777215 300 25;每当听到这首歌我心里就百感交集 34 16776960 0 25;烟花易逝,人情长存 0 16776960 180 25;此生无悔二次元,来世还做纸片人 116 15138834 60 25;还能坚持下去等一个人吗,已经错过了一整个青春 31 16777215 90 25;宋老师,您一定要幸福,我才不会遗憾 5 8700107 210 25;把灯火都灭掉,拨动寒冷的月光 66 16765698 180 25;打上军火 0 6830715 30 25;有情人终成兄妹(狗头) 110 15138834 270 25;等到有彩虹,你的脸亮起美丽的容光 40 16765698 90 25;这懵懂的感情在内心迸发 31 16765698 210 25;众所周知,治愈等于致郁 34 16777215 210 25;那天留连的海岸 10 8700107 120 25;我将沉沦于二次元某个对立的街头,那是我所热衷于 2 15138834 330 25;此生无悔二次元,来世愿做画中人 110 15138834 30 25;烟花易逝人情长存 35 16777215 0 25;魈————! 57 16755202 30 25;你这话说的太真实了,单身使我们相遇 94 16777215 60 25;愿有一天你能和重要的人再次重逢 88 16777215 90 25;烟花从正面看是圆的,从侧面看是爱人的脸庞 5 16777215 180 25;你的名字 71 16777215 300 25;天气之子 63 16777215 150 25;最后来个萤火之森就绝杀了 78 16777215 330 25;懦夫表白墙 27 15138834 330 25;らららららららら 97 16777215 90 25;永远永远喜欢哈娜! 36 41194 0 25;依婷我爱你!!! 53 16777215 300 25;天气之子 63 16777215 300 25;八爷是神 13 16777215 60 25;所愿皆所得 10 52480 240 25;愿所愿皆所得 7 16777215 90 25;八爷!!!!!!! 38 15138834 150 25;八爷!!!!!! 26 15138834 210 25;希望跨过屏幕的界限,与你相遇在现实 41 16777215 180 25;蒂诺我喜欢你 19 16777215 60 25;谢谢 119 16777215 30 25;daoko声音好听 81 16777215 150 25;邵若燕我爱你 98 16777215 90 25;一转眼四年过去了(2024来) 23 15138834 330 25;记得我和你一起的时光 90 41194 210 25;[ohh] 70 16777215 300 25;真的超级好听啊!!! 0 15138834 60 25;if!!!!里面的if 54 16777215 330 25;天气之子 38 16777215 270 25;哈哈 35 16777215 240 25;夏舜妍活下去 58 16777215 150 25;拜托xsy活下去吧 46 16777215 330 25;故事里的她终成遗憾 25 16777215 60 25;[ohh] 68 16777215 210 25;再见他 45 16777215 90 25;5刷烟花了,神作 5 16777215 270 25;哦太平間褲衩味兒 6 16777215 240 25;姓赖的女孩,我要告诉你,很快我也要释怀啦 39 16777215 300 25;黎小茗我喜欢你 37 8700107 90 25;[前方高能] 29 16777215 0 25;金鱼来啦!!! 25 16740868 60 25;天气之子 63 16777215 240 25;gly我喜欢你 5 16777215 150 25;你的名字 73 16777215 210 25;吴润泽,抱歉啊! 58 41194 330 25;送你每一个盛夏 116 16777215 0 25;苏若优 33 16777215 90 25;你的名字 71 16777215 270 25;天气之子 63 16777215 240 25;llx。。我还是,一如以往四年般,喜欢你 56 16777215 120 25;李依琳我爱你 67 16777215 150 25;此生不悔二次元 34 41194 60 25;czh我爱你 44 16777215 120 25;秒速五厘米 34 16777215 300 25;烟花 31 16777215 150 25;陈思维!!!!! 58 16777215 180 25;贾若溪,我喜欢你 85 16646914 210 25;你的名字 71 16777215 150 25;你的名字 72 16777215 240 25;[ohh] 66 16777215 0 25;"
set FFMPEG_CMD=ffplay -i "%VIDEO_FILE%" -vf "
for %%A in ("%TEXT_INFO:;=";"%") do (
    ::echo Processing: %%~A
    set count=0
    for %%B in (%%~A) do (
        set /a count+=1
        set "ITEM!count!=%%~B"
    )
    :: FreeSerif.ttf
    set "FFMPEG_CMD=!FFMPEG_CMD!drawtext=fontsize=!ITEM5!:text='!ITEM1!':x=w-100*(t-!ITEM2!):y=!ITEM4!:enable=gt(t\,!ITEM2!),"
)
set FFMPEG_CMD=!FFMPEG_CMD:~0,-1!"
!FFMPEG_CMD!
endlocal

可以先生成一段视频, 然后在继续前面的操作

@echo off
setlocal enabledelayedexpansion
set VIDEO_FILE=hy.mp4
set "TEXT_INFO=⭐———————— 27 16777215 300 25;我在叙利亚都没受过这么重的伤 107 16776960 270 25;底部淡蓝色字幕菌施工完毕,感谢欣赏 96 8700107 270 25;“升空的烟火,是圆的,还是扁的?”“圆的也好,扁的也好,奇怪形状也罢。只要我们俩在一起,什么我都不在乎。” 35 16646914 30 25;烟花易逝,人情长存 3 16707842 270 25;樱花易逝,春树常绿,以声之色,塑以花之形,将你之名,刻之我心。 75 16777215 270 25;赶快去表白,别留遗憾!!! 55 16646914 30 25;君(きみ)の後(うし)ろ姿(すがた)你留下背影的那天 15 9033215 300 25;焰色反应() 26 16707842 240 25;此时,西片正在找高木 99 15138834 270 25;底部淡蓝色中文字幕君开始施工,并非翻译 7 8700107 240 25;2022中考顺利!加油!! 35 16707842 270 25;↑说句人话:我爱你西宫硝子↑ 38 16776960 180 25;两年了,我已经放下啦 20 16707842 300 25;烟花易逝,人情长存 13 15138834 0 25;烟花易逝,人情长存 91 16777215 300 25;每当听到这首歌我心里就百感交集 34 16776960 0 25;烟花易逝,人情长存 0 16776960 180 25;此生无悔二次元,来世还做纸片人 116 15138834 60 25;还能坚持下去等一个人吗,已经错过了一整个青春 31 16777215 90 25;宋老师,您一定要幸福,我才不会遗憾 5 8700107 210 25;把灯火都灭掉,拨动寒冷的月光 66 16765698 180 25;打上军火 0 6830715 30 25;有情人终成兄妹(狗头) 110 15138834 270 25;等到有彩虹,你的脸亮起美丽的容光 40 16765698 90 25;这懵懂的感情在内心迸发 31 16765698 210 25;众所周知,治愈等于致郁 34 16777215 210 25;那天留连的海岸 10 8700107 120 25;我将沉沦于二次元某个对立的街头,那是我所热衷于 2 15138834 330 25;此生无悔二次元,来世愿做画中人 110 15138834 30 25;烟花易逝人情长存 35 16777215 0 25;魈————! 57 16755202 30 25;你这话说的太真实了,单身使我们相遇 94 16777215 60 25;愿有一天你能和重要的人再次重逢 88 16777215 90 25;烟花从正面看是圆的,从侧面看是爱人的脸庞 5 16777215 180 25;你的名字 71 16777215 300 25;天气之子 63 16777215 150 25;最后来个萤火之森就绝杀了 78 16777215 330 25;懦夫表白墙 27 15138834 330 25;らららららららら 97 16777215 90 25;永远永远喜欢哈娜! 36 41194 0 25;依婷我爱你!!! 53 16777215 300 25;天气之子 63 16777215 300 25;八爷是神 13 16777215 60 25;所愿皆所得 10 52480 240 25;愿所愿皆所得 7 16777215 90 25;八爷!!!!!!! 38 15138834 150 25;八爷!!!!!! 26 15138834 210 25;希望跨过屏幕的界限,与你相遇在现实 41 16777215 180 25;蒂诺我喜欢你 19 16777215 60 25;谢谢 119 16777215 30 25;daoko声音好听 81 16777215 150 25;邵若燕我爱你 98 16777215 90 25;一转眼四年过去了(2024来) 23 15138834 330 25;记得我和你一起的时光 90 41194 210 25;[ohh] 70 16777215 300 25;真的超级好听啊!!! 0 15138834 60 25;if!!!!里面的if 54 16777215 330 25;天气之子 38 16777215 270 25;哈哈 35 16777215 240 25;夏舜妍活下去 58 16777215 150 25;拜托xsy活下去吧 46 16777215 330 25;故事里的她终成遗憾 25 16777215 60 25;[ohh] 68 16777215 210 25;再见他 45 16777215 90 25;5刷烟花了,神作 5 16777215 270 25;哦太平間褲衩味兒 6 16777215 240 25;姓赖的女孩,我要告诉你,很快我也要释怀啦 39 16777215 300 25;黎小茗我喜欢你 37 8700107 90 25;[前方高能] 29 16777215 0 25;金鱼来啦!!! 25 16740868 60 25;天气之子 63 16777215 240 25;gly我喜欢你 5 16777215 150 25;你的名字 73 16777215 210 25;吴润泽,抱歉啊! 58 41194 330 25;送你每一个盛夏 116 16777215 0 25;苏若优 33 16777215 90 25;你的名字 71 16777215 270 25;天气之子 63 16777215 240 25;llx。。我还是,一如以往四年般,喜欢你 56 16777215 120 25;李依琳我爱你 67 16777215 150 25;此生不悔二次元 34 41194 60 25;czh我爱你 44 16777215 120 25;秒速五厘米 34 16777215 300 25;烟花 31 16777215 150 25;陈思维!!!!! 58 16777215 180 25;贾若溪,我喜欢你 85 16646914 210 25;你的名字 71 16777215 150 25;你的名字 72 16777215 240 25;[ohh] 66 16777215 0 25;"
set FFMPEG_CMD=ffmpeg -i "%VIDEO_FILE%" -vf "
for %%A in ("%TEXT_INFO:;=";"%") do (
    ::echo Processing: %%~A
    set count=0
    for %%B in (%%~A) do (
        set /a count+=1
        set "ITEM!count!=%%~B"
    )
    set "FFMPEG_CMD=!FFMPEG_CMD!drawtext=fontsize=!ITEM5!:text='!ITEM1!':x=w-100*(t-!ITEM2!):y=!ITEM4!:enable=gt(t\,!ITEM2!),"
)
set FFMPEG_CMD=!FFMPEG_CMD:~0,-1!" 
:: 视频输出
!FFMPEG_CMD! output.mp4 

这里的中文输出可能会有乱码, 在cmd中输入chcp 65001, 就可以切换为UTF-8模式

弹幕提取

比如bilibili的, 可以通过网址获取, 我想要的是https://comment.bilibili.com/215991800.xml, 这里面是xml文件, 先将文件下载下来, 然后使用任何一门编程语言做xml解析, 我使用的是java

package com.wpl.tool;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
import java.util.Random;

public class DOMParser {
    static StringBuilder stringBuilder = new StringBuilder();
    static int unit = 30;
    static int height = 360;
    static int count = height/unit;
    static int duration = 120;
    static int durationD = 289;
    public static void main(String[] args) {
        int c = 0;
        stringBuilder.append("set \"TEXT_INFO=");
        try {
            File xmlFile = new File("src/main/resources/215991800.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(xmlFile);
            doc.getDocumentElement().normalize();

            //System.out.println("Root element: " + doc.getDocumentElement().getNodeName());

            NodeList nodeList = doc.getElementsByTagName("d");
            //System.out.println("nodeList.getLength() "+nodeList.getLength());
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                Element element = (Element) node;
                //System.out.println(node.getTextContent());
                String p = element.getAttribute("p");
                String[] strings = p.split(",");
                String context = node.getTextContent();
                String startTime0 = strings[0];
                String[] preStartTime = startTime0.split("\\.");
                int startTime = Integer.parseInt(preStartTime[0])*duration/durationD;
                // Integer.parseInt(strings[2])+height+""
                String fontSize =strings[2];
                Random random = new Random();
                int randomNumber = random.nextInt(count);
                String y = randomNumber*unit+"";
                String color = strings[3]; //十六进制
                color = Integer.toHexString(Integer.parseInt(color));
                while(color.length()!=6){
                    color = "0"+color;
                }
                context = context.replace(" ", "");
                context = context.replace(",", ",");
                c++;
                stringBuilder.append(context+" "+startTime +" "+"#"+color+" "+y+" "+fontSize+";");
                if(c==100){
                    stringBuilder.append("\"");
                    System.out.println(stringBuilder.toString());
                    c=0;
                    stringBuilder.setLength(0);
                    stringBuilder.append("set \"TEXT_INFO=");
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

最后结果为这个样子
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容