TS视频文件转MP4文件的两种方法

TS视频文件转MP4文件的两种方法

文章目录

  • TS视频文件转MP4文件的两种方法
  • 前言
    • ts文件转mp4文件的两种方法 1.通过javacv中的方法实现对ts文件进行转换(会在同目录下生成同名的mp4文件) 2.通过视频流方式生成mp4文件(需提前创建一个mp4文件)
  • 一、HLS,m3u8文件,ts是什么?
  • 二、方法1:通过Javacv来实现视频转换
    • 1.引入库
    • 2.读入数据
  • 三、方法2:通过视频流来实现视频转换
    • 1.url转字节
    • 2.文件转字节
    • 3.通过输入流获得二进制数据
    • 4.将二进制流转换为文件
    • 5.实现方法
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

ts文件转mp4文件的两种方法
1.通过javacv中的方法实现对ts文件进行转换(会在同目录下生成同名的mp4文件)
2.通过视频流方式生成mp4文件(需提前创建一个mp4文件)

提示:以下是本篇文章正文内容,下面案例可供参考

一、HLS,m3u8文件,ts是什么?

● HLS协议:HTTP Live Streaming用于播放.ts视频,它是苹果公司实现的基于HTTP的流媒体传输协议,可以实现流媒体的直播和点播。关键组成有m3u8和多个视频分片.ts
● m3u8(hls的index文件):是指UTF-8编码格式的M3U文件。M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。
● .ts:视频格式:是日本高清摄像机拍摄下进行的封装格式,可使用.WinDVD 5.x、VLC Media Player、Elecard Player播放器播放;
○ mp4:一种兼容性非常好的视频格式,几乎所有的媒体设备都支持mp4格式。
○ TS比较清晰,因为TS一般封装原盘,码率比较足,mp4是压制过来的,采用先进的编码技术和合理的参数来弥补低码率编码的不足

二、方法1:通过Javacv来实现视频转换

1.引入库

代码如下(示例):

<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.4.4</version>
        </dependency>

2.读入数据

代码如下(示例):

public class VideoUtils {
    private static final Logger log = LoggerFactory.getLogger(VideoUtils.class);

    //转换后的视频格式
    private static final String VIDEO_FORMAT =  ".mp4";

    public static void main(String[] args) throws Exception {
        VideoUtils.convertToMp4(new File("D:\\cs\\test\\14.ts"));

    }

    /**
* 转换视频文件为mp4
* @param file 目标视频文件
*/
    public static void convertToMp4(File file) throws FrameRecorder.Exception, FrameGrabber.Exception {
        long startTime = System.currentTimeMillis();
        log.info("开始进行ts格式转MP4。。。");

        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(file);
        //视频比率,与清晰度有关
        grabber.setVideoBitrate(2000000);

        //转储后mp4文件地址
        String fileName = file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + VIDEO_FORMAT;;

        Frame frame = null;

        FFmpegFrameRecorder recorder = null;

        try {
            grabber.start();
            log.info("FFmpegFrameGrabber start已耗时:{}ms", (System.currentTimeMillis() - startTime));

            recorder = new FFmpegFrameRecorder(fileName, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());
            recorder.setVideoCodec(grabber.getVideoCodec());
            recorder.setFormat(VIDEO_FORMAT);
            recorder.setFrameRate(grabber.getFrameRate());
            recorder.setVideoBitrate(grabber.getVideoBitrate());
            recorder.start();

            log.info("FFmpegFrameRecorder start已耗时:{}ms", (System.currentTimeMillis() - startTime));

            long changeSize = 0L;
            while ((frame = grabber.grabFrame()) != null) {
                recorder.setTimestamp(grabber.getTimestamp());
                recorder.record(frame);
                changeSize++;
            }

            log.info("视频转换总耗时:{}ms, 完成帧数:{}", (System.currentTimeMillis() - startTime), changeSize);
            log.info("转换后的视频地址:{}", fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            log.info("开始关闭FFmpegFrameGrabber、FFmpegFrameRecorder流链接。。。");
            recorder.stop();
            recorder.release();
            grabber.stop();
        }
    }
}

三、方法2:通过视频流来实现视频转换

1.url转字节

/**
     * 
	 * url转字节
     * @param urlPath http://xxx.com/xxxx/xx.ts
     * @return 字节
     * @throws Exception
     */
public static byte[] bbb(String urlPath) throws Exception {

        URL url = new URL(urlPath);
        //打开链接
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置请求方式为"GET"
        conn.setRequestMethod("GET");
        //超时响应时间为5秒  q
        conn.setConnectTimeout(5 * 1000);
        //通过输入流获取图片数据
        InputStream inStream = conn.getInputStream();
        byte[] data = readInputStream(inStream);
        return data;
    }

2.文件转字节

/**
     * 文件转字节
     * @param path "D://xxx/xxx.ts"
     * @return
     * @throws Exception
     */
public static byte[] ccc(String path) throws Exception {
        File file = new File(path);
        InputStream inputStream = new FileInputStream(file);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int n = 0;
        while (-1 != (n = inputStream.read(buffer))){
            outputStream.write(buffer,0,n);
        }
        return outputStream.toByteArray();
    }

3.通过输入流获得二进制数据

/**
     * 通过输入流获得二进制数据
     * @param inStream
     * @return data 字节
     * @throws Exception
     */
    private static byte[] readInputStream(InputStream inStream) throws Exception{
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度,如果为-1,代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while( (len=inStream.read(buffer)) != -1 ){
            //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }

4.将二进制流转换为文件

/**
     * 将二进制流转换为文件
     * @param bytes fileName(自定义文件)
     * @return
     */
    public static String bytes2File(byte[] bytes,String fileName){
        File file = new File(fileName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try (FileOutputStream outputStream = new FileOutputStream(fileName);){
            outputStream.write(bytes);
            return fileName;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

5.实现方法

 public static void main(String[] args) throws Exception {
      //ts为http url
       byte[] bbb = bbb("http://xxx.com/xxxx/xx.ts");
      //ts为本地路径
      byte[] ccc = ccc("D:\\cs\\test\\14-28_0.ts");
       //   "D:\\cs\\cs\\cs.mp4" 自己创建的文件  
       bytes2File(bbb,"D:\\cs\\cs\\cs.mp4");
     }

总结

提示:这里对文章进行总结:

此次的业务是 通过ts的path 以mp4后缀下载到本地

/**
     * 下载mp4文件
     * @param response
     * @param videoUrlPath 文件存在的路径“D/test/xxx.ts”
     */
    @Override
    public void downloadMp4(HttpServletResponse response, String videoUrlPath) {
        try {
            File file = new File(videoUrlPath);
            String filename = file.getName();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(videoUrlPath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename.split("\\.")[0]+".mp4", "utf-8"));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/x-download");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

你可能感兴趣的:(java)