热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何用GStreamer删除H264格式的中间部分视频

本文讨论了如何使用GStreamer来删除H264格式视频文件中的中间部分,而不需要进行重编码。作者提出了使用gst_element_seek(...)函数来实现这个目标的思路,并提到遇到了一个解决不了的BUG。文章还列举了8个解决方案,希望能够得到更好的思路。
需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

8 个解决方案

#1


引用 楼主 neicole 的回复:
需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。

#2


引用 1 楼 neustar1 的回复:
Quote: 引用 楼主 neicole 的回复:

需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。


谢谢~ 那意思是如果非纯I帧,不管用哪些思路,都必须得重编码?

#3


引用 2 楼 neicole 的回复:
Quote: 引用 1 楼 neustar1 的回复:

Quote: 引用 楼主 neicole 的回复:

需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。


谢谢~ 那意思是如果非纯I帧,不管用哪些思路,都必须得重编码?

是的,但是不需要完全重新编码,只需要编码衔接段那几帧,譬如找到30s的之前的I帧到30s这几帧,还有后面那些帧。

#4


引用 3 楼 neustar1 的回复:
Quote: 引用 2 楼 neicole 的回复:

Quote: 引用 1 楼 neustar1 的回复:

Quote: 引用 楼主 neicole 的回复:

需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。


谢谢~ 那意思是如果非纯I帧,不管用哪些思路,都必须得重编码?

是的,但是不需要完全重新编码,只需要编码衔接段那几帧,譬如找到30s的之前的I帧到30s这几帧,还有后面那些帧。


噢,我想我明白意思了~ 

只是这样子我就产生了进一步的疑惑了,在GStreamer里面,要做到编码衔接的话,貌似是不行。
因为按我理解的话,貌似每个组件产生的src都是一个整体了,无法在中途做一些其它的操作,然后再继续进行组件内部操作。

#5


引用 4 楼 neicole 的回复:
Quote: 引用 3 楼 neustar1 的回复:

Quote: 引用 2 楼 neicole 的回复:

Quote: 引用 1 楼 neustar1 的回复:

Quote: 引用 楼主 neicole 的回复:

需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。


谢谢~ 那意思是如果非纯I帧,不管用哪些思路,都必须得重编码?

是的,但是不需要完全重新编码,只需要编码衔接段那几帧,譬如找到30s的之前的I帧到30s这几帧,还有后面那些帧。


噢,我想我明白意思了~ 

只是这样子我就产生了进一步的疑惑了,在GStreamer里面,要做到编码衔接的话,貌似是不行。
因为按我理解的话,貌似每个组件产生的src都是一个整体了,无法在中途做一些其它的操作,然后再继续进行组件内部操作。

利用现成的组件肯定是不行了,如果执意要用GST,只能自己写组件了。
用ffmpeg,我想会来的更简单一些,但是也需要编码。

#6


引用 5 楼 neustar1 的回复:
Quote: 引用 4 楼 neicole 的回复:

Quote: 引用 3 楼 neustar1 的回复:

Quote: 引用 2 楼 neicole 的回复:

Quote: 引用 1 楼 neustar1 的回复:

Quote: 引用 楼主 neicole 的回复:

需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。


谢谢~ 那意思是如果非纯I帧,不管用哪些思路,都必须得重编码?

是的,但是不需要完全重新编码,只需要编码衔接段那几帧,譬如找到30s的之前的I帧到30s这几帧,还有后面那些帧。


噢,我想我明白意思了~ 

只是这样子我就产生了进一步的疑惑了,在GStreamer里面,要做到编码衔接的话,貌似是不行。
因为按我理解的话,貌似每个组件产生的src都是一个整体了,无法在中途做一些其它的操作,然后再继续进行组件内部操作。

利用现成的组件肯定是不行了,如果执意要用GST,只能自己写组件了。
用ffmpeg,我想会来的更简单一些,但是也需要编码。


噢~ 话说,我在上网查资料的时候,找到关于一个叫Segnment的组件:
A segment event is sent downstream to announce the range of valid timestamps in the stream and how they should be transformed into running-time and stream-time. A segment event must always be sent before the first buffer of data and after a flush (see above).
于是我就产生了这么一种思路,先将视频分割,然后,再将它们合起来,通过事件截取,在视频分割到指定位置后,再进行下一步的分割,然后再将它们输出到同一个文件当中。

即:假如: filesrc -> qtdemux -> mp4mux -> filesink, 那么,我在qtdemux那里截取流,写入seek事件(像范围播放的那个事件),本事件起的作用就是读取并且操作第一段的数据,然后,当知道这事件结束后,再进行下一段的数据设置。
gst_element_seek(qtdemux, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_SEGMENT, time_start1, time_end1);
但是不确定可不可行,如果会有问题,问题会出现在哪?

还不能上机尝试,因为我在做程序的时候遇到了一个问题,一直卡住,第三天了,一直在找资料还没解决,mp4mux接收了audio和video的sink后,设置pipeline的状态为GST_STATE_PLAYING,但不能成功,当我试着将它们一个个元素地尝试的时候,发现filesink一直都只能设置到READY状态。
但如果我只接收一个流(只要audio或者video)这就能成功了,很是困惑。

#7


引用 6 楼 neicole 的回复:
Quote: 引用 5 楼 neustar1 的回复:

Quote: 引用 4 楼 neicole 的回复:

Quote: 引用 3 楼 neustar1 的回复:

Quote: 引用 2 楼 neicole 的回复:

Quote: 引用 1 楼 neustar1 的回复:

Quote: 引用 楼主 neicole 的回复:

需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。


谢谢~ 那意思是如果非纯I帧,不管用哪些思路,都必须得重编码?

是的,但是不需要完全重新编码,只需要编码衔接段那几帧,譬如找到30s的之前的I帧到30s这几帧,还有后面那些帧。


噢,我想我明白意思了~ 

只是这样子我就产生了进一步的疑惑了,在GStreamer里面,要做到编码衔接的话,貌似是不行。
因为按我理解的话,貌似每个组件产生的src都是一个整体了,无法在中途做一些其它的操作,然后再继续进行组件内部操作。

利用现成的组件肯定是不行了,如果执意要用GST,只能自己写组件了。
用ffmpeg,我想会来的更简单一些,但是也需要编码。


噢~ 话说,我在上网查资料的时候,找到关于一个叫Segnment的组件:
A segment event is sent downstream to announce the range of valid timestamps in the stream and how they should be transformed into running-time and stream-time. A segment event must always be sent before the first buffer of data and after a flush (see above).
于是我就产生了这么一种思路,先将视频分割,然后,再将它们合起来,通过事件截取,在视频分割到指定位置后,再进行下一步的分割,然后再将它们输出到同一个文件当中。

即:假如: filesrc -> qtdemux -> mp4mux -> filesink, 那么,我在qtdemux那里截取流,写入seek事件(像范围播放的那个事件),本事件起的作用就是读取并且操作第一段的数据,然后,当知道这事件结束后,再进行下一段的数据设置。
gst_element_seek(qtdemux, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_SEGMENT, time_start1, time_end1);
但是不确定可不可行,如果会有问题,问题会出现在哪?

还不能上机尝试,因为我在做程序的时候遇到了一个问题,一直卡住,第三天了,一直在找资料还没解决,mp4mux接收了audio和video的sink后,设置pipeline的状态为GST_STATE_PLAYING,但不能成功,当我试着将它们一个个元素地尝试的时候,发现filesink一直都只能设置到READY状态。
但如果我只接收一个流(只要audio或者video)这就能成功了,很是困惑。

具体实现就要你去试验了,

#8


引用 7 楼 neustar1 的回复:
Quote: 引用 6 楼 neicole 的回复:

Quote: 引用 5 楼 neustar1 的回复:

Quote: 引用 4 楼 neicole 的回复:

Quote: 引用 3 楼 neustar1 的回复:

Quote: 引用 2 楼 neicole 的回复:

Quote: 引用 1 楼 neustar1 的回复:

Quote: 引用 楼主 neicole 的回复:

需求:
假设现在有一段H264视频文件,视频长度为60s,现在需要将其中的30-39s的内容去掉,视频处理后总长为50s。

请问是否能够不通过重编码实现。(即不用上coder/encoder)

我的思路:
gst-launch-1.0 filesrc location=... ! qtdemux ! mp4mux ! filesink location=...

打算在编程时使用gst_element_seek(...)来将中间的秒数去掉,但不确定这方法是否可行,现在在编程过程中遇上了不知道如何解决的BUG (http://bbs.csdn.net/topics/390748487),所以还没能往下试。请问这思路是否可行,是否有其它更佳思路?

这个不一定可行,因为关键帧的位置问题,如果是纯I帧,理论上可行。但是如果存在B,P帧,则不可行。


谢谢~ 那意思是如果非纯I帧,不管用哪些思路,都必须得重编码?

是的,但是不需要完全重新编码,只需要编码衔接段那几帧,譬如找到30s的之前的I帧到30s这几帧,还有后面那些帧。


噢,我想我明白意思了~ 

只是这样子我就产生了进一步的疑惑了,在GStreamer里面,要做到编码衔接的话,貌似是不行。
因为按我理解的话,貌似每个组件产生的src都是一个整体了,无法在中途做一些其它的操作,然后再继续进行组件内部操作。

利用现成的组件肯定是不行了,如果执意要用GST,只能自己写组件了。
用ffmpeg,我想会来的更简单一些,但是也需要编码。


噢~ 话说,我在上网查资料的时候,找到关于一个叫Segnment的组件:
A segment event is sent downstream to announce the range of valid timestamps in the stream and how they should be transformed into running-time and stream-time. A segment event must always be sent before the first buffer of data and after a flush (see above).
于是我就产生了这么一种思路,先将视频分割,然后,再将它们合起来,通过事件截取,在视频分割到指定位置后,再进行下一步的分割,然后再将它们输出到同一个文件当中。

即:假如: filesrc -> qtdemux -> mp4mux -> filesink, 那么,我在qtdemux那里截取流,写入seek事件(像范围播放的那个事件),本事件起的作用就是读取并且操作第一段的数据,然后,当知道这事件结束后,再进行下一段的数据设置。
gst_element_seek(qtdemux, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_SEGMENT, time_start1, time_end1);
但是不确定可不可行,如果会有问题,问题会出现在哪?

还不能上机尝试,因为我在做程序的时候遇到了一个问题,一直卡住,第三天了,一直在找资料还没解决,mp4mux接收了audio和video的sink后,设置pipeline的状态为GST_STATE_PLAYING,但不能成功,当我试着将它们一个个元素地尝试的时候,发现filesink一直都只能设置到READY状态。
但如果我只接收一个流(只要audio或者video)这就能成功了,很是困惑。

具体实现就要你去试验了,


哈哈,好吧,谢啦~

推荐阅读
  • 本文介绍了关于Java异常的八大常见问题,包括异常管理的最佳做法、在try块中定义的变量不能用于catch或finally的原因以及为什么Double.parseDouble(null)和Integer.parseInt(null)会抛出不同的异常。同时指出这些问题是由于不同的开发人员开发所导致的,不值得过多思考。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本博文基于《Amalgamationofproteinsequence,structureandtextualinformationforimprovingprote ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • Question该提问来源于开源项目:react-native-device-info/react-native-device-info ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了10分钟了解Android的事件分发相关的知识,希望对你有一定的参考价值。什么是事件分发?大家 ... [详细]
  • Android跨进程通信IPC之9——Binder通信机制
    移步系列Android跨进程通信IPC系列1Android整体架构Android系统架构及系统源码目录Android系统架构 ... [详细]
  • 当程序到后台后,继续完成LongRunning Task 任务
    原文:http:blog.sina.com.cnsblog_7b9d64af0101cjci.html(2013-04-0921:27:24)我们知道, ... [详细]
author-avatar
mobiledu2502874455
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有