Golang调用FFmpeg转换视频流的实现

目录
  • 问题背景
  • 方法实现
    • 1. 使用FFmpeg-go封装好的方法
    • 2. 直接调用FFmpeg
  • 总结

问题背景

问题背景是在,由于视频采集端使用的是H264编码采集的裸流,而网络流媒体大多是以FLV为主的直播方式进行的,为了实现实时直播,当前是打算直接使用FFmpeg将H264裸流实时转成FLV视频流。

为什么是使用FLV视频流呢,因为相对简单,加上FLV Header后将每个NALU打包成Tag并进去大致就行了。但是这块怕有疏忽,最终还是想使用成熟的工具FFmpeg。

方法实现

1. 使用FFmpeg-go封装好的方法

FFmpeg-go

上面有具体的Demo,但是只有流转文件,也只有文件转流的方法,对于流转流还是需要自己动手处理一下。

import ffmpeg "github.com/u2takey/ffmpeg-go"
 
err := ffmpeg.Input("pipe:", ffmpeg.KwArgs{
        "format":     "rawvideo",
        "video_size": fmt.Sprintf("%dx%d", 480, 1064)}).WithInput(filein).
        Output("pipe:",
            ffmpeg.KwArgs{"c:v": "libx264", "f": "flv", "crf": "24"}).
        WithOutput(buf, errorbuf).
        Run()
if err != nil {
        panic(err)
}
bufs := make([]byte, 1024)
out, _ := os.OpenFile("res2.flv", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
for {
    n, err := buf.Read(bufs)
    if n == 0 || err == io.EOF {
        out.Close()
        break
    } else {
        //此处处理输出流,这边简单地写到文件里
        out.Write(bufs)
    }
}

其中

filein   是输入的H264视频裸流   buf是输出的视频流
虽说代码是这么写,但是实际上是run不起来的,不清楚具体是什么原因,因此后续还是打算直接调用ffmpeg可执行程序。

2. 直接调用FFmpeg

首先需要在电脑上下载好ffmpeg并且添加到环境变量,保证执行Powshell或者cmd指令的ffmpeg时能够正常运行,接下来还是直接上代码。

cmd := exec.Command("ffmpeg", "-re", "-r", "30", "-i", "pipe:0", "-vcodec", "libx264", "-f", "flv", "pipe:1", "-y", "another.flv")

//获取输入流
stdin, err := cmd.StdinPipe()
if err != nil {
    fmt.Println("Error getting stdout pipe:", err)
    return
}

//要写东西进去的时候只需要
stdin.Write(bytes) 

//获取输出流
stdout, err := cmd.StdoutPipe()
if err != nil {
    fmt.Println("Error getting stdout pipe:", err)
    return
}

// Start the command
err = cmd.Start()
if err != nil {
    fmt.Println("Error starting command:", err)
    return
}

这边需要注意到的点是,如果不加上"-re"的话,需要等stdin.close()之后,整个ffmpeg才会运行,才能见到有输出流。

其次,这边加了 “-y” "another.flv",是用来进行对比的,这里ffmpeg将会把输出同时放在两个地方,一个写入到文件another.flv里(-y 是覆盖原有文件),另一个通过stdout传出来,我将stdout的数据流保存成out.flv后发现同another.flv对比发现并不相同。或许视频流和文件不应该这么处理。

总结

建议直接调用FFmpeg的可执行文件进行操作最好。

但是这样实时的流转流的方式实际上还是有挺大延迟的,如果要实时视频流P2P模式建议要么在采集端处理好要么在播放端处理好,中间层就不要过多操作影响实时性,如果是推流拉流的模式还是建议在中间层处理好。

存在问题
这边还是发现一些问题的,尤其是直接使用ffmpeg的时候

1. 直接读取文件和读取文件通过stdin传入byte获取到的结果是不一致的。

2. 直接output成文件和通过stdout获取byte再保存成文件得到的结果也是不一致的。

到此这篇关于Golang调用FFmpeg转换视频流的实现的文章就介绍到这了,更多相关Golang FFmpeg转换视频流内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go语言调用ffmpeg-api实现音频重采样

    目录 前言 环境部署 代码 总结 前言 最近对golang处理音视频很感兴趣,对golang音视频常用库goav进行了一番研究.自己写了一个wav转采样率的功能.给大家分享一下,中间遇到了不少坑,解决的过程中还是蛮有意思的. 环境部署 代码运行在Ubuntu环境上,需要使用到goav,goav是对ffmpeg源码的golang封装. goav地址:https://github.com/giorgisio/goav goav安装如下 sudo apt-get -y install autoconf

  • go后端利用ffmpeg转hls做简单视频直播

    目录 1. 前言 2. wsl安装ffmpeg并转换rtsp为hls 3. 前后端示例代码 3.1 后端go代码 3.2 前端代码 4. 结果及评估 1. 前言 上一次我们找到一些开源方案,目前我们先测试一下ffmpeg转hls播放的方式,看下延迟情况及兼容性情况,主要测试Windows.Linux和macOS中使用谷歌浏览器播放的情况.后端结合我们之前的cgo部分,建立一个简单的http服务器,然后提供给前端调用. 2. wsl安装ffmpeg并转换rtsp为hls sudo apt-get

  • Golang调用FFmpeg转换视频流的实现

    目录 问题背景 方法实现 1. 使用FFmpeg-go封装好的方法 2. 直接调用FFmpeg 总结 问题背景 问题背景是在,由于视频采集端使用的是H264编码采集的裸流,而网络流媒体大多是以FLV为主的直播方式进行的,为了实现实时直播,当前是打算直接使用FFmpeg将H264裸流实时转成FLV视频流. 为什么是使用FLV视频流呢,因为相对简单,加上FLV Header后将每个NALU打包成Tag并进去大致就行了.但是这块怕有疏忽,最终还是想使用成熟的工具FFmpeg. 方法实现 1. 使用FF

  • 详解java调用ffmpeg转换视频格式为flv

    详解java调用ffmpeg转换视频格式为flv 注意:下面的程序是在Linux下运行的,如果在windows下rmvb转换成avi会出现问题,想成功需要下载下个drv43260.dll东西放到C:WindowsSystem32下面 这几天在写一个视频管理系统,遇到一个很大的问题就是如果把不同格式转换为flv,格式!经过网上的一番搜索,自己在总结,整理,整理,终于整出来了!实现了视频进行转换的同时还能够进行视频截图和删除原文件的功能! 格式转换主要原理就是先用java调用ffmpeg的exe文件

  • java调用ffmpeg实现视频转换的方法

    本文实例讲述了java调用ffmpeg实现视频转换的方法.分享给大家供大家参考.具体分析如下: 这里环境我是在windows平台下测试的... 需要在e:\下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4个文件.   还要在e:\input下放各种文件名为a的以下各种视频文件:还要e:\output:java程序执行后能得到一个a.flv的已转换的文件. ffmpeg.exe能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov

  • java调用ffmpeg实现转换视频

    最近由于项目需要把不同格式的视频转换为ts流,故研究了一下ffmpeg.在网上找了很多资料,主要参考了Java+Windows+ffmpeg实现视频转换功能. 期间也加了几个qq群,咨询了各大高手,其中在代码中关于ffmpeg的命令就是来自其中一个qq群里面的大神. 下载相关文件 ffmpeg地址,我下载是windows 64位static版本. xuggler下载地址 下面的代码我上传到了github,需要的可以下载下来看看. 步骤: 1.研究java如何调用外部程序 2.研究ffmpeg转换

  • php 调用ffmpeg获取视频信息的简单实现

    ffmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序,包含了libavcodec,保证高可移值性和编解码质量. 本文将介绍使用php调用ffmpeg获取视频信息,调用ffmpeg首先需要服务器上安装了ffmpeg,安装方法很简单,可自行搜索. 代码如下: <?php // 定义ffmpeg路径及命令常量 define('FFMPEG_CMD', '/usr/local/bin/ffmpeg -i "%s" 2>&1'); /** *

  • C# 调用FFmpeg处理音视频的示例

    FFmpeg 开源.跨平台.体积小.功能强大,提供了录制.转换以及流化音视频的完整解决方案. 官网:https://www.ffmpeg.org/ 百科:https://baike.baidu.com/item/ffmpeg/2665727?fr=aladdin FFmpeg 应用非常广泛,可以用来播放本地视频甚至网络视频,查看音视频信息,还可以用于从视频中提取音频,转换音视频文件格式等等,本文主要介绍如何调用 FFmpeg 来查看音视频信息.从视频中提取音频.转换音视频格式等. 1. 调用FF

  • java调用FFmpeg实现视屏压缩功能的详细步骤

    目录 前言 实现步骤 一.在windows系统中下载对应的FFmpeg 二.FFmpeg压缩视屏命令 三.java实现FFmpeg命令调用 注意事项 1.文件名 2.视屏参数 前言 最近做人脸识别,对于过大的视屏(10M)以上,识别失败的几率比较大.找了下相关的视屏压缩资料.首先使用的是jave进行视屏压缩,但是踩坑失败,jave中有转码的过程,虽然压缩成功,各种压缩参数也调整了一大堆,但是在识别时,几乎都不会成功,但是只是压缩观看的话,还是可以使用jave的.继续踩坑,直接使用原生的FFmpe

  • C#调用FFmpeg操作音视频的实现示例

    目录 项目背景 FFmpeg介绍 FFmpeg相关教程 博客示例源码 下载FFmpeg.exe安装包 C#进程调用FFmpeg操作音视频 项目背景 因为公司需要对音视频做一些操作,比如说对系统用户的发音和背景视频进行合成,以及对多个音视频之间进行合成,还有就是在指定的源背景音频中按照对应的规则在视频的多少秒钟内插入一段客户发音等一些复杂的音视频操作.本篇文章主要讲解的是使用C#进程(Process)调用FFmpeg.exe进行视频合并,音频合并,音频与视频合并成视频这几个简单的音视频操作,还有些

  • PHP调用ffmpeg对视频截图并拼接脚本

    PHP脚本调用ffmpeg对视频截图并拼接,供大家参考,具体内容如下 目前支持MKV,MPG,MP4等常见格式的视频,其他格式有待测试 12P 一张截图平均生成时间  1.64s     100个视频,大概需要2分半左右 9P  一张截图平均生成时间  1.13s      100个视频,大概需要2分钟左右 6P  一张截图平均生成时间  0.86s      100个视频,大概需要1分半左右 3P  一张截图平均生成时间  0.54s      100个视频,大概需要1分钟左右 <?php d

  • Python3.6.2调用ffmpeg的方法

    本文是为了学习python调用C语言的库写的例子. 去ffmpeg官网下载编译好的avcodec-57.dll.avutil-55.dll.swresample-2.dll,准备好了C语言写出的库. 下面是用Python调用的例子. import os import ctypes dllHandler = ctypes.cdll.LoadLibrary(os.getcwd() + '\\avcodec-57.dll') ret = dllHandler.avcodec_configuration

随机推荐