• 视频剪辑去除水印小工具


    零、直接下载

    百度网盘链接:https://pan.baidu.com/s/1b8IvB4q-e2VVWR2uKikuQQ

    提取码:1edz

    解压,双击运行RemoveWatermark.exe即可使用。


    一、背景

    现在B站越来越火,需要用到视频剪辑工具,我也试了几款免费的视频剪辑工具,发现免费试用,不成为会员,都会给你的视频加上水印。我平时不怎么使用视频剪辑,就偶尔用一下,因此,我就想着要去除水印,因此开发了这款小工具。

    二、实现思路

    1、因为视频剪辑软件的水印基本都打在上方,有如下情况:

    水印1  水印3

    首先要把原图像往上拓展一些黑色区域,得到如下效果:

    步骤1

    2、把预处理好的视频送到视频剪辑软件处理,水印就打在拓展区域上了:

    步骤2

    3、对打上水印的视频进行后处理,把带水印的上方区域裁切掉,就得到去水印后的效果:

    步骤3

    三、代码实现:

    开发环境:win10 + QT5.7.1

    依赖库:opencv3.1.0 + ffmpeg-4.3

    1、pro工程设置

    #opencv
    INCLUDEPATH += C:Opencv3.1.0opencvuildincludeopencv
                C:Opencv3.1.0opencvuildincludeopencv2
                C:Opencv3.1.0opencvuildinclude
    LIBS += C:Opencv3.1.0opencvuildx64vc14libopencv_world310.lib
    
    #ffmpeg
    INCLUDEPATH += D:3rdPartyffmpeg-4.3ffmpeg-4.3-win64-devinclude
    LIBS += D:3rdPartyffmpeg-4.3ffmpeg-4.3-win64-devlib*.lib

    2、预处理(区域拓展)代码片段

    cv::VideoWriter writer(preSaveName.toStdString(), CV_FOURCC('M', 'J', 'P', 'G'), 30, cv::Size(width, heightExtern));//
        cv::Mat frame;
        cv::Mat frameExtern = cv::Mat::zeros(heightExtern, width, CV_8UC3);
    
        while (1)
        {
            cap >> frame;
            if (frame.empty())
            {
                break;
            }
            frame.copyTo(frameExtern(rect));
            //cv::inpaint(frame, mask, frame, 7.0, cv::INPAINT_TELEA);
            writer << frameExtern;
            cv::imshow("frame", frameExtern);
            cv::waitKey(10);
        }
        cap.release();

    3、后处理(crop)代码片段

        av_register_all();  //ffmpeg程序的第一句,注册库
    
        AVFormatContext *afc = NULL;
        int width = 0;
        int height = 0;
        int time_length = 0;
    
        //打开视频文件
        int nRet = avformat_open_input(&afc, inputFileName.c_str(), 0, 0);
        if (nRet < 0)
        {
            std::cout << "can't find file!" << std::endl;
        }
        else
        {
            std::cout << "open file success!" << std::endl;
        }
        int durTime = afc->duration / AV_TIME_BASE;  //视频时间 4分20秒
        std::cout << "durTime = " << durTime << std::endl;
        unsigned int numberOfStream = afc->nb_streams;  //包含流的个数2:一个视频流一个音频流
        std::cout << "numberOfStream = " << numberOfStream << std::endl;
    
        for (int i = 0; i < afc->nb_streams; i++)
        {
            AVCodecContext *acc = afc->streams[i]->codec;
            if (acc->codec_type == AVMEDIA_TYPE_VIDEO)  //如果是视频类型
            {
                std::cout << "AVMEDIA_TYPE_VIDEO" << std::endl;
                AVCodec *codec = avcodec_find_decoder(acc->codec_id);
                if (!codec)
                {
                    std::cout << "no decoder!" << std::endl;
                }
                width = acc->width;
                height = acc->height;
                std::cout << "width = " << width << ", height = " << height << std::endl;
    
                int ret = avcodec_open2(acc, codec, NULL);
                if (ret != 0)
                {
                    char buf[1024] = { 0 };
                    av_strerror(ret, buf, sizeof(buf));
                }
    
                std::cout << "open decoder success!" << std::endl;
            }
            if (acc->codec_type == AVMEDIA_TYPE_AUDIO)
            {
                std::cout << "AVMEDIA_TYPE_AUDIO" << std::endl;
            }
        }
    
        if (afc)
        {
            std::cout << "avformat_close_input" << std::endl;
            avformat_close_input(&afc);  //关闭视频流
            std::cout << "avformat_close_input close" << std::endl;
        }
    
        //处理
        int x = 0;
        int y = height*0.2;
        time_length = durTime - 5;//去除最后5s的视频
        char cmd[128] = { 0 };
        //crop
        sprintf(cmd, "ffmpeg -i %s -vf crop='1280:720:%d:%d' -acodec copy %s", inputFileName.c_str(), x, y, outputFileName.c_str());
        //crop,去除尾部
        //sprintf(cmd, "ffmpeg -i expand_miao.mp4 -vf crop='1280:720:%d:%d' -acodec copy -ss 00:00:00 -t %d remove_water2.mp4", x, y, time_length);
        std::string str = cmd;
        std::cout << "str = " << str << std::endl;
        system(cmd);

    四、使用场景

    该小工具适用于所有水印在上方的情况。

    五、界面

    image image

    六、使用步骤

    1、使用小工具先进行预处理

    (1)点击“视频文件导入”按钮,选择原始视频;

    (2)设置输出文件名,默认存放在D盘根目录下,avi格式(现在暂时只支持这种格式);

    (3)点击开始预处理按钮,等待处理完成。

    2、视频剪辑软件处理

    3、使用小工具进行后处理

    (1)点击“视频文件导入”按钮,选择视频剪辑软件处理好的视频;

    (2)设置输出文件名,默认存放在D盘根目录下,可以支持mp4格式;

    (3)点击开始后处理按钮,等待处理完成。

    七、小工具下载地址

    如果不想自己开发,我也提供了编译好的小工具,供大家下载使用:

    百度网盘链接:https://pan.baidu.com/s/1b8IvB4q-e2VVWR2uKikuQQ

    提取码:1edz

    解压,双击运行RemoveWatermark.exe即可使用。

    end

  • 相关阅读:
    在C#中使用官方驱动操作MongoDB
    【C#设计模式-抽象工厂模式】
    【MongoDB-MongoVUE图像管理工具】
    【MongoDB-query查询条件】
    【MongoDB学习-安装流程】
    【MongoDB学习-在.NET中的简单操作】
    【MongoDB】2.可视化工具的安装和使用
    越狱Season 1-Episode 12:Odd Man Out
    越狱Season 1-Episode 11: And Then There Were 7-M
    越狱Season 1-Episode 10: Sleight of Hand
  • 原文地址:https://www.cnblogs.com/smbx-ztbz/p/13309517.html
Copyright © 2020-2023  润新知