您好,登錄后才能下訂單哦!
前面已經把視頻成功的上傳到我們的服務器,選擇了背景音樂的ID,現在需要把視頻和背景音樂進行合并,需要使用一個工具ffmpeg。源碼:https://github.com/limingios/wxProgram.git 中wx-springboot 和 No.15
介紹
>視音頻處理工具,跨平臺的視音頻處理解決方案,主頁:http://ffmpeg.org
應用的場景
播放器:射手播放器,暴風影音,迅雷播放器……
轉換工具:格式工廠,剪輯工具……
直播,視頻加碼,濾鏡,水印,特效……
下載
根據你的需求進行下載,我選擇在windows平臺來進行下載
測試
C:UsersAdministrator>D: D:>cd?D:Program?Filesffmpeg D:Program?Filesffmpeg>cd?bin D:Program?Filesffmpegbin>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:?h364?(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?(h364?(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程序調用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
D:Program?Filesffmpegbin>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); ????} }
PS:已經完成了視頻的上傳,并把相關的信息保存在數據庫中。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。