「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

栏目: Java · 发布时间: 6年前

内容简介:前面已经把视频成功的上传到我们的服务器,选择了背景音乐的ID,现在需要把视频和背景音乐进行合并,需要使用一个工具ffmpeg。源码:https://github.com/limingios/wxProgram.git 中wx-springboot 和 No.15根据你的需求进行下载,我选择在windows平台来进行下载

前面已经把视频成功的上传到我们的服务器,选择了背景音乐的ID,现在需要把视频和背景音乐进行合并,需要使用一个工具ffmpeg。源码:https://github.com/limingios/wxProgram.git 中wx-springboot 和 No.15

ffmpeg

  • 介绍

    >视音频处理工具,跨平台的视音频处理解决方案,主页:http://ffmpeg.org

「小程序 <a href='https://www.codercto.com/topics/22013.html'>JAVA</a> 实战」小程序视频处理工具ffmpeg(46)

  • 应用的场景
  1. 播放器:射手播放器,暴风影音,迅雷播放器……
  2. 转换工具:格式工厂,剪辑工具……
  3. 直播,视频加码,滤镜,水印,特效……
  • 下载

    「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

根据你的需求进行下载,我选择在windows平台来进行下载

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

  • 测试

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

C:\Users\Administrator>D:

D:\>cd D:\Program Files\ffmpeg

D:\Program Files\ffmpeg>cd bin

D:\Program Files\ffmpeg\bin>ffmpeg.exe -i shanzhu.mp4 shanzhu.avi
ffmpeg version N-91949-g6304268e39 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 8.2.1 (GCC) 20180813
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth
  libavutil      56. 19.101 / 56. 19.101
  libavcodec     58. 30.100 / 58. 30.100
  libavformat    58. 18.100 / 58. 18.100
  libavdevice    58.  4.103 / 58.  4.103
  libavfilter     7. 31.100 /  7. 31.100
  libswscale      5.  2.100 /  5.  2.100
  libswresample   3.  2.100 /  3.  2.100
  libpostproc    55.  2.100 / 55.  2.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'shanzhu.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2018-09-16T05:29:47.000000Z
  Duration: 00:00:09.34, start: 0.000000, bitrate: 1210 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 544x960, 1159 kb/s, 29.97 fps, 29.97 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2018-09-16T05:29:47.000000Z
      handler_name    : Core Media Video
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 46 kb/s (default)
    Metadata:
      creation_time   : 2018-09-16T05:29:47.000000Z
      handler_name    : Core Media Audio
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> mpeg4 (native))
  Stream #0:1 -> #0:1 (aac (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, avi, to 'shanzhu.avi':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    ISFT            : Lavf58.18.100
    Stream #0:0(und): Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 544x960, q=2-31, 200 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc (default)
    Metadata:
      creation_time   : 2018-09-16T05:29:47.000000Z
      handler_name    : Core Media Video
      encoder         : Lavc58.30.100 mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
    Stream #0:1(und): Audio: mp3 (libmp3lame) (U[0][0][0] / 0x0055), 44100 Hz, mono, fltp (default)
    Metadata:
      creation_time   : 2018-09-16T05:29:47.000000Z
      handler_name    : Core Media Audio
      encoder         : Lavc58.30.100 libmp3lame
frame=  280 fps=0.0 q=31.0 Lsize=    1096kB time=00:00:09.34 bitrate= 961.3kbits/s speed=16.7x
video:999kB audio:72kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.338377%

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

  • java程序调用cmd转换视频

springboot-common中添加FFMpegTest

package com.idig8.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class FFMpegTest {

    private String ffmpegEXE;

    public FFMpegTest(String ffmpegEXE) {
        super();
        this.ffmpegEXE = ffmpegEXE;
    }

    public void convertor(String videoInputPath, String videoOutputPath) throws Exception {
//      ffmpeg -i input.mp4 -y output.avi
        List<String> command = new ArrayList<>();
        command.add(ffmpegEXE);

        command.add("-i");
        command.add(videoInputPath);
        command.add("-y");
        command.add(videoOutputPath);

        for (String c : command) {
            System.out.print(c + " ");
        }

        ProcessBuilder builder = new ProcessBuilder(command);
        Process process = builder.start();

        InputStream errorStream = process.getErrorStream();
        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
        BufferedReader br = new BufferedReader(inputStreamReader);

        String line = "";
        while ( (line = br.readLine()) != null ) {
        }

        if (br != null) {
            br.close();
        }
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
        if (errorStream != null) {
            errorStream.close();
        }

    }

    public static void main(String[] args) {
        FFMpegTest ffmpeg = new FFMpegTest("D:\\Program Files\\ffmpeg\\bin\\ffmpeg.exe");
        try {
            ffmpeg.convertor("D:\\Program Files\\ffmpeg\\bin\\shanzhu.mp4", "D:\\Program Files\\ffmpeg\\bin\\shanzhu.avi");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
  • 视频音频合并命令

    > 通过这种方式,可以让我们的mp4和我们的mp3 做一个结合。

ffmpeg.exe -i shanzhu.avi -i music.mp3 -t 10 -y 合并音乐和视频.avi

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

D:\Program Files\ffmpeg\bin>ffmpeg.exe -i shanzhu.avi -i music.mp3 -t 10 -y 合并音乐和视频.avi
ffmpeg version N-91949-g6304268e39 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 8.2.1 (GCC) 20180813
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth
  libavutil      56. 19.101 / 56. 19.101
  libavcodec     58. 30.100 / 58. 30.100
  libavformat    58. 18.100 / 58. 18.100
  libavdevice    58.  4.103 / 58.  4.103
  libavfilter     7. 31.100 /  7. 31.100
  libswscale      5.  2.100 /  5.  2.100
  libswresample   3.  2.100 /  3.  2.100
  libpostproc    55.  2.100 / 55.  2.100
Input #0, avi, from 'shanzhu.avi':
  Metadata:
    encoder         : Lavf58.18.100
  Duration: 00:00:09.38, start: 0.000000, bitrate: 957 kb/s
    Stream #0:0: Video: mpeg4 (Simple Profile) (FMP4 / 0x34504D46), yuv420p, 544x960 [SAR 1:1 DAR 17:30], 876 kb/s, 29.97 fps, 29.97 tbr, 29.97 tbn, 30k tbc
    Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 44100 Hz, mono, fltp, 64 kb/s
[mp3 @ 000001fcfa57d6c0] Estimating duration from bitrate, this may be inaccurate
Input #1, mp3, from 'music.mp3':
  Duration: 00:00:33.47, start: 0.000000, bitrate: 320 kb/s
    Stream #1:0: Audio: mp3, 48000 Hz, stereo, fltp, 320 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg4 (native) -> mpeg4 (native))
  Stream #1:0 -> #0:1 (mp3 (mp3float) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, avi, to '鍚堝苟闊充箰鍜岃棰?avi':
  Metadata:
    ISFT            : Lavf58.18.100
    Stream #0:0: Video: mpeg4 (FMP4 / 0x34504D46), yuv420p(progressive), 544x960 [SAR 1:1 DAR 17:30], q=2-31, 200 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc
    Metadata:
      encoder         : Lavc58.30.100 mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
    Stream #0:1: Audio: mp3 (libmp3lame) (U[0][0][0] / 0x0055), 48000 Hz, stereo, fltp
    Metadata:
      encoder         : Lavc58.30.100 libmp3lame
frame=  280 fps=274 q=31.0 Lsize=    1076kB time=00:00:10.00 bitrate= 880.4kbits/s speed=9.79x
video:892kB audio:157kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.510280%
  • java程序调用cmd转换视频增加音频
package com.idig8.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class MergeVideoMp3 {

    private String ffmpegEXE;

    public MergeVideoMp3(String ffmpegEXE) {
        super();
        this.ffmpegEXE = ffmpegEXE;
    }

    public void convertor(String videoInputPath, String mp3InputPath,
            double seconds, String videoOutputPath) throws Exception {
//      ffmpeg.exe -i 苏州大裤衩.mp4 -i bgm.mp3 -t 7 -y 新的视频.mp4
        List<String> command = new ArrayList<>();
        command.add(ffmpegEXE);

        command.add("-i");
        command.add(videoInputPath);

        command.add("-i");
        command.add(mp3InputPath);

        command.add("-t");
        command.add(String.valueOf(seconds));

        command.add("-y");
        command.add(videoOutputPath);

//      for (String c : command) {
//          System.out.print(c + " ");
//      }

        ProcessBuilder builder = new ProcessBuilder(command);
        Process process = builder.start();

        InputStream errorStream = process.getErrorStream();
        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
        BufferedReader br = new BufferedReader(inputStreamReader);

        String line = "";
        while ( (line = br.readLine()) != null ) {
        }

        if (br != null) {
            br.close();
        }
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
        if (errorStream != null) {
            errorStream.close();
        }

    }

    public static void main(String[] args) {
        MergeVideoMp3 ffmpeg = new MergeVideoMp3("D:\\Program Files\\ffmpeg\\bin\\ffmpeg.exe");
        try {
            ffmpeg.convertor("D:\\Program Files\\ffmpeg\\bin\\shanzhu.mp4", "D:\\Program Files\\ffmpeg\\bin\\music.mp3", 7.1, "D:\\Program Files\\ffmpeg\\bin\\合并音乐和视频.avi");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

开发功能

视频上传后通过java调用ffmpge.exe完成音乐和视频的合并,并将视频信息保存在数据库中。

  • 视频service开发

    VideoService

package com.idig8.service;

import com.idig8.pojo.Videos;

public interface VideoService {


    /**
     * 保存视频信息
     * @param Id
     * @return
     */
    public void saveVideo(Videos video);
}

VideoServiceImpl

package com.idig8.service.Impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.idig8.mapper.BgmMapper;
import com.idig8.pojo.Bgm;
import com.idig8.service.BgmService;

@Service
public class BgmServiceImpl implements BgmService {

    @Autowired
    private BgmMapper bgmMapper;


    @Transactional(propagation =Propagation.SUPPORTS)
    @Override
    public List<Bgm> queryBgmList(){

        return bgmMapper.selectAll();
    }

    @Transactional(propagation =Propagation.SUPPORTS)
    @Override
    public Bgm queryBgmById(String Id){

        return bgmMapper.selectByPrimaryKey(Id);
    }

}

BgmService

package com.idig8.service;

import java.util.List;

import com.idig8.pojo.Bgm;

public interface BgmService {

    /**
     * 获取所有的Bgm列表
     * @return
     */
    public List<Bgm> queryBgmList();

    /**
     * 通过bgmId获取Bgm对象
     * @param Id
     * @return
     */
    public Bgm queryBgmById(String Id);
}

BgmServiceImpl

package com.idig8.service.Impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.idig8.mapper.BgmMapper;
import com.idig8.pojo.Bgm;
import com.idig8.service.BgmService;

@Service
public class BgmServiceImpl implements BgmService {

    @Autowired
    private BgmMapper bgmMapper;


    @Transactional(propagation =Propagation.SUPPORTS)
    @Override
    public List<Bgm> queryBgmList(){

        return bgmMapper.selectAll();
    }

    @Transactional(propagation =Propagation.SUPPORTS)
    @Override
    public Bgm queryBgmById(String Id){

        return bgmMapper.selectByPrimaryKey(Id);
    }

}

VideoController

package com.idig8.controller;

import java.io.File;
import java.util.Date;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.idig8.pojo.Bgm;
import com.idig8.pojo.Videos;
import com.idig8.service.BgmService;
import com.idig8.service.VideoService;
import com.idig8.utils.JSONResult;
import com.idig8.utils.MergeVideoMp3;
import com.idig8.utils.enums.VideoStatusEnum;
import com.idig8.utils.file.FileUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;


@RestController
@Api(value="视频相关业务的接口", tags= {"视频相关业务的controller"})
@RequestMapping("/video")
public class VideoController extends BasicController {

    @Autowired
    private BgmService bgmService;

    @Autowired
    private VideoService videosService;

    @Value("${server.file.path}")
    private String fileSpace;

    @Value("${server.ffmpeg.path}")
    private String ffmpegexe;


    @ApiOperation(value="上传视频", notes="上传视频的接口")
    @ApiImplicitParams({
        @ApiImplicitParam(name="userId", value="用户id", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="bgmId", value="背景音乐id", required=false, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoSeconds", value="背景音乐播放长度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoWidth", value="视频宽度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="videoHeight", value="视频高度", required=true, 
                dataType="String", paramType="form"),
        @ApiImplicitParam(name="desc", value="视频描述", required=false, 
                dataType="String", paramType="form")
    })
    @PostMapping(value="/upload", headers="content-type=multipart/form-data")
    public JSONResult upload(String userId, 
                String bgmId, double videoSeconds, 
                int videoWidth, int videoHeight,
                String desc,
                @ApiParam(value="短视频", required=true)
                MultipartFile file) throws Exception {

        if (StringUtils.isBlank(userId)) {
            return JSONResult.errorMsg("用户id不能为空...");
        }
        // 文件保存的命名空间
        String fileName = file.getOriginalFilename();
        // 保存到数据库中的相对路径
        String path = "";
        String videOutPath = "";
        try {
             path = FileUtil.uploadFile(file.getBytes(), fileSpace, fileName);
            } catch (Exception e) {
                e.getStackTrace();
                   return JSONResult.errorMsg(e.getMessage());
            }                


        if(StringUtils.isNotBlank(bgmId)){
            Bgm bgm = bgmService.queryBgmById(bgmId);
            String mp3BgmPath = fileSpace + bgm.getPath();
            MergeVideoMp3 mergeVideoMp3 = new MergeVideoMp3(ffmpegexe);
            String videOutPathName = UUID.randomUUID().toString()+".mp4";
            File targetFile = new File(fileSpace + userId);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            videOutPath = "/"+userId+"/"+videOutPathName;
            String videoInput = fileSpace +path;
            mergeVideoMp3.convertor(videoInput, mp3BgmPath, videoSeconds, fileSpace +videOutPath);
        }


        Videos videos = new Videos();
        videos.setAudioId(bgmId);
        videos.setCreateTime(new Date());
        videos.setVideoDesc(desc);
        videos.setId(UUID.randomUUID().toString());
        videos.setUserId(userId);
        videos.setVideoHeight(videoHeight);
        videos.setVideoWidth(videoWidth);
        videos.setVideoPath(videOutPath);
        videos.setStatus(VideoStatusEnum.SUCCESS.value);
        videosService.saveVideo(videos);

        return JSONResult.ok(path);

    }
}

「小程序JAVA实战」小程序视频处理工具ffmpeg(46)

PS:已经完成了视频的上传,并把相关的信息保存在数据库中。

百度未收录

>>原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!

>>原文链接地址:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming in Haskell

Programming in Haskell

Graham Hutton / Cambridge University Press / 2007-1-18 / GBP 34.99

Haskell is one of the leading languages for teaching functional programming, enabling students to write simpler and cleaner code, and to learn how to structure and reason about programs. This introduc......一起来看看 《Programming in Haskell》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换