zoukankan      html  css  js  c++  java
  • JavaCV音视频转单声道16位16K赫兹小端点pcm音频

      先用Java CV的拉流对象实现对音视频的格式转换:

      1、音视频转纯音频

      2、音频指定采样率和声道  

      接着手动搞定采用率的位深,对音频做16位位深和小端点转换。最后把转好的字节数组写入文件,这个简单,用一个IO处理流对象搞定,看代码:

    import org.bytedeco.javacv.FFmpegFrameGrabber;
    import org.bytedeco.javacv.Frame;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.nio.Buffer;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.ShortBuffer;
    
    /**
     * 音视频转单声道16位16K赫兹小端点pcm音频
     */
    public class PCMFileProduce {
    
        public static void main(String[] args) throws Exception {
            String path = "E:\BaiduNetdiskDownload\roundDeskS02E01.mp4"; //待转音视频
            File file = new File("E:\BaiduNetdiskDownload\pcmTest.pcm"); //目标文件
    
            OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
    
            FFmpegFrameGrabber frameGrabber = FFmpegFrameGrabber.createDefault(path);
            frameGrabber.setSampleRate(16000); //16K赫兹采样率
            frameGrabber.setAudioChannels(1); //单声道
            frameGrabber.start();
    
            Frame frame;
            Buffer buffer;
            short[] shorts;
            byte[] bytes;
    
            System.out.println("开始转换文件");
            while ((frame = frameGrabber.grabSamples()) != null) {
                if (frame.samples == null) {
                    continue;
                }
                buffer = frame.samples[0];
    
                shorts = new short[buffer.limit()];
                ((ShortBuffer) buffer).get(shorts);
                bytes = shortArr2byteArr(shorts, buffer.limit());
    
                os.write(bytes);
            }
    
            os.close(); // 关闭写文件
            frameGrabber.close(); // 直接关闭拉流
            System.out.println("转换结束");
        }
    
        /**
         * 8位字节数组转16位字节数组,也就是16位的采样位深,转小端点字节数组
         *
         * @param shortArr
         * @param shortArrLen
         * @return
         */
        private static byte[] shortArr2byteArr(short[] shortArr, int shortArrLen) {
            byte[] byteArr = new byte[shortArrLen * 2];
            ByteBuffer.wrap(byteArr).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shortArr);
            return byteArr;
        }
    
    }

      看输出:

    Connected to the target VM, address: '127.0.0.1:50289', transport: 'socket'
    开始转换文件
    转换结束
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:BaiduNetdiskDownload
    oundDeskS02E01.mp4':
      Metadata:
        major_brand     : isom
        minor_version   : 512
        compatible_brands: isomiso2avc1mp41
        encoder         : Lavf58.20.100
      Duration: 00:39:54.27, start: 0.000000, bitrate: 815 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1080x606, 744 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default)
        Metadata:
          handler_name    : VideoHandler
        Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 64 kb/s (default)
        Metadata:
          handler_name    : SoundHandler
    Disconnected from the target VM, address: '127.0.0.1:50289', transport: 'socket'
    
    Process finished with exit code 0

      比较下ffmpeg和上面代码转换的两个文件:

      命令行转换参见:ffmpeg音视频转单声道16位16K赫兹小端点pcm音频

  • 相关阅读:
    mysql主从配置的过程
    redis 命令行客户端utf8中文乱码问题
    十五分钟介绍 Redis数据结构--学习笔记
    70路小报:用PV和UV作为网站衡量指标已经过时
    安装redis环境
    网站统计IP PV UV实现原理
    服务器启动脚本 /etc/rc.local
    LeetCode: Longest Valid Parentheses
    LeetCode: Next Permutation & Permutations1,2
    LeetCode: divideInteger
  • 原文地址:https://www.cnblogs.com/wuxun1997/p/13438374.html
Copyright © 2011-2022 走看看