为了账号安全,请及时绑定邮箱和手机立即绑定

H5使用Video标签上传视频有声音无画面的解决方案

标签:
Java Html5
  • 前端用H5的Video标签做了播放器,部分mp4文件上传成功后只有声音而没有画面,经过了解之后才知道此标签只支持编码为H264的MP4文件,不支持编码为MPEG4的MP4文件,想成功播放必须要转码。于是就去网上找啊找,刚开始全是格式化工厂转,但是我要的是可以用代码实现的。。。但最后找到一种折中的方法,就是拿ffmpeg工具结合代码来完成转码。

  • 当然了,首先得检测该MP4的编码是哪种类型,如果是H264,那就不用转了直接上传就好了,否则就需要转码。这是检测的代码。(ps:因为用的是maven项目,而中央仓库找不到这个依赖,还得手动打包到本地仓库。。。这是jar包地址,下1.0.2版本的。)
    http://www.sauronsoftware.it/projects/jave/download.php
Encoder encoder = new Encoder();
File target1 = new File(path);
MultimediaInfo info3 = encoder.getInfo(target1);
System.out.println(info3);

**输出结果如下:**
it.sauronsoftware.jave.MultimediaInfo (format=mov, duration=115200, video=it.sauronsoftware.jave.VideoInfo (decoder=h264, size=it.sauronsoftware.jave.VideoSize (width=1280, height=720), bitRate=-1, frameRate=25.0), audio=it.sauronsoftware.jave.AudioInfo (decoder=mpeg4aac, samplingRate=44100, channels=2, bitRate=-1))
  • 其中video是视频信息,audio则是音频信息,duration是视频长度。。。其他参数不一一说明了。。。最重要的是decoder这个参数,如果是h264那么恭喜你不用转码,但如果是mpeg4那么就只能转码了!
  • 要转码就必须要有ffmpeg工具,也算是千辛万苦最后在csdn花了金币下载了一个,直接贴代码:
 public static boolean changeVCodec(String inputFile, String outputFile) {
        List<String> command= new ArrayList<String>();
        command.add("ffmpeg工具的本地路径");
        command.add("-i");
        command.add(inputFile);// 要转的文件路径
        command.add("-vcodec");
        command.add("h264"); // 设置自己想要的视频编码信息
        command.add("-acodec"); 
        command.add("copy");// 因为对音频没改变需求,所以直接copy
        command.add("-f");
        command.add("mov");
        command.add("-y");
        command.add(outputFile); // 转码之后的文件路径
        StringBuffer test = new StringBuffer();
        for (int i = 0; i < command.size(); i++) {
            test.append(command.get(i) + " ");
        }

        log.info("转换编码和接收文件的信息:" + test);

        try {
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(command);
            builder.start();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static void main(String[] args) {
        changeVCodec(source,target);
    }
  • 这样在windows上就转码成功了,是通过 "ProcessBuilder "这个类来操作系统进程;当然在linux上还没试验,不出意外是没有问题的!
    最后原MPEG4的MP4文件通过转码之后也能成功播放了!
  • 如果哪位老哥老姐有更好的方法,还请指导!

今天再次测试时碰到个问题,就是用项目实现转码如果不做流的处理,那么需要等的时间非常长,一个2分钟的视频足足等了25分钟。25分钟够好多男士来好几发了。。。后来想到把输入和错误流给读出来,结果同一个2分钟的视频虽然也要等,但只等了35秒,还能接收

        InputStream inputStream = null;
        InputStream errorStream = null;
        try {
            Process p = Runtime.getRuntime().exec(command.toArray(new String[command.size()]));
            inputStream = p.getInputStream();
            errorStream = p.getErrorStream();
            BufferedReader inputBr = new BufferedReader(new InputStreamReader(inputStream));
            BufferedReader errorBr = new BufferedReader(new InputStreamReader(errorStream));
            new Thread(){
                public void run(){
                    String inputLine = null;
                    StringBuffer inputBuffer = new StringBuffer();
                    try {
                        while ((inputLine = inputBr.readLine()) != null){
                            inputBuffer.append(inputLine);
                        }
                        log.info("转码文件的输入流" + inputBuffer.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        if(null != inputBr){
                            try {
                                inputBr.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }.start();
            //
            new Thread(){
                public void run(){
                    String errorLine = null;
                    StringBuffer errorBuffer = new StringBuffer();
                    try {
                        while ((errorLine = errorBr.readLine()) != null){
                            errorBuffer.append(errorLine);
                        }
                        log.info("转码文件的错误流:" + errorBuffer.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        if(null != errorBr){
                            try {
                                errorBr.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }.start();
            flag = true;
        } catch (Exception e) {
            throw new CommunityException("转换MP4编码失败");
        }finally {
            if(null != inputStream){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(null != errorStream){
                try {
                    errorStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
点击查看更多内容
5人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
8
获赞与收藏
23

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消