gstreamer基础教程12-Streaming

Gstreamer 应用开发:1-基础介绍 介绍开始围绕如何用命令实现一个音视频混合,或者单独的音频,和单独的视频文件如何实现播放,并逐步开始使用C语言程序来实现之前我们用命令行来实现的功能 阅读详情

索引:https://blog.youkuaiyun.com/knowledgebao/article/details/84621238

Goal

Playing media straight直接 from the Internet without storing it locally is known as Streaming. We have been doing it throughout the tutorials whenever we used a URI starting with http://. This tutorial shows a couple of additional points to keep in mind when streaming. In particular:

  • How to enable buffering (to alleviate network problems)
  • How to recover from interruptions中断 (lost clock)

Introduction

流播放由于缓存原因,可能数据块延迟,导致播放暂停。一般的解决方案是,设置缓存。播放稍微延迟一点,增加一点缓存,保证数据你能够正常播放。可以对消息GST_MESSAGE_BUFFERING进行处理,进而控制视频的播放和暂停。

为了保持各个流之间的通过,会参考系统时钟,但是系统时钟有可能会发生变化,通过监听GST_MESSAGE_CLOCK_LOST消息,结合暂停开始,达到重置系统基准的问题。

When streaming, media chunks are decoded and queued for presentation as soon as they arrive form the network. This means that if a chunk is delayed (which is not an uncommon situation at all on the Internet) the presentation queue might run dry and media playback could stall.

The universal一般通用 solution is to build a “buffer”, this is, allow a certain number of media chunks to be queued before starting playback. In this way, playback start is delayed a bit, but, if some chunks are late, reproduction is not impacted影响 as因为 there are more chunks in the queue, waiting.

As it turns out事实证明, this solution is already implemented实施 in GStreamer, but the previous tutorials have not been benefiting受益 from it. Some elements, like the queue2 and multiqueue found inside playbin, are capable of building this buffer and post bus messages regarding the buffer level (the state of the queue). An application wanting to have more network resilience弹性, then, should listen to these messages and pause playback if the buffer level is not high enough (usually, whenever每当 it is below 100%).

To achieve synchronization同步 among multiple sinks (for example and audio and a video sink) a global clock is used. This clock is selected by GStreamer among all elements which can provide one. Under some circumstances情况, for example, an RTP source switching streams or changing the output device, this clock can be lost and a new one needs to be selected. This happens mostly when dealing with streaming, so the process is explained解释 in this tutorial.

When the clock is lost, the application receives a message on the bus; to select a new one, the application just needs to set the pipeline to PAUSED and then to PLAYING again.

A network-resilient example

Copy this code into a text file named basic-tutorial-12.c.

basic-tutorial-12.c

#include <gst/gst.h>
#include <string.h>

typedef struct _CustomData {
  gboolean is_live;
  GstElement *pipeline;
  GMainLoop *loop;
} CustomData;

static void cb_message (GstBus *bus, GstMessage *msg, CustomData *data) {

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ERROR: {
      GError *err;
      gchar *debug;

      gst_message_parse_error (msg, &err, &debug);
      g_print ("Error: %s\n", err->message);
      g_error_free (err);
      g_free (debug);

      gst_element_set_state (data->pipeline, GST_STATE_READY);
      g_main_loop_quit (data->loop);
      break;
    }
    case GST_MESSAGE_EOS:
      /* end-of-stream */
      gst_element_set_state (data->pipeline, GST_STATE_READY);
      g_main_loop_quit (data->loop);
      break;
    case GST_MESSAGE_BUFFERING: {
      gint percent = 0;

      /* If the stream is live, we do not care about buffering. */
      if (data->is_live) break;

      gst_message_parse_buffering (msg, &percent);
      g_print ("Buffering (%3d%%)\r", percent);
      /* Wait until buffering is complete before start/resume playing */
      if (percent < 100)
        gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
      else
        gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
      break;
    }
    case GST_MESSAGE_CLOCK_LOST:
      /* Get a new clock */
      gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
      gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
      break;
    default:
      /* Unhandled message */
      break;
    }
}

int main(int argc, char *argv[]) {
  GstElement *pipeline;
  GstBus *bus;
  GstStateChangeReturn ret;
  GMainLoop *main_loop;
  CustomData data;

  /* Initialize GStreamer */
  gst_init (&argc, &argv);

  /* Initialize our data structure */
  memset (&data, 0, sizeof (data));

  /* Build the pipeline */
  pipeline = gst_parse_launch ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);
  bus = gst_element_get_bus (pipeline);

  /* Start playing */
  ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    g_printerr ("Unable to set the pipeline to the playing state.\n");
    gst_object_unref (pipeline);
    return -1;
  } else if (ret == GST_STATE_CHANGE_NO_PREROLL) {
    data.is_live = TRUE;
  }

  main_loop = g_main_loop_new (NULL, FALSE);
  data.loop = main_loop;
  data.pipeline = pipeline;

  gst_bus_add_signal_watch (bus);
  g_signal_connect (bus, "message", G_CALLBACK (cb_message), &data);

  g_main_loop_run (main_loop);

  /* Free resources */
  g_main_loop_unref (main_loop);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;
}

This tutorial opens a window and displays a movie, with accompanying audio. The media is fetched from the Internet, so the window might take a few seconds to appear, depending on your connection speed. In the console window, you should see a buffering message, and playback should only start when the buffering reaches 100%. This percentage might not change at all if your connection is fast enough and buffering is not required.

Walkthrough

需要关注的是直播流,直播流没有暂停状态,所以设置播放后返回值不是GST_STATE_CHANGE_SUCCESS 而是GST_STATE_CHANGE_NO_PREROLL。

The only special thing this tutorial does is react to certain messages; therefore, the initialization code is very simple and should be self-explanative by now. The only new bit is the detection of live streams:

/* Start playing */
ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
  g_printerr ("Unable to set the pipeline to the playing state.\n");
  gst_object_unref (pipeline);
  return -1;
} else if (ret == GST_STATE_CHANGE_NO_PREROLL) {
  data.is_live = TRUE;
}

Live streams cannot be paused, so they behave in PAUSED state as if they were in the PLAYING state. Setting live streams to PAUSED succeeds, but returns GST_STATE_CHANGE_NO_PREROLL, instead of GST_STATE_CHANGE_SUCCESS to indicate that this is a live stream. We are receiving the NO_PREROLL return code even though we are trying to set the pipeline to PLAYING, because state changes happen progressively逐渐 (from NULL to READY, to PAUSED and then to PLAYING).

We care about live streams because we want to disable buffering for them, so we take note of the result of gst_element_set_state() in the is_live variable.

Let’s now review the interesting parts of the message parsing callback:

case GST_MESSAGE_BUFFERING: {
  gint percent = 0;

  /* If the stream is live, we do not care about buffering. */
  if (data->is_live) break;

  gst_message_parse_buffering (msg, &percent);
  g_print ("Buffering (%3d%%)\r", percent);
  /* Wait until buffering is complete before start/resume playing */
  if (percent < 100)
    gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
  else
    gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
  break;
}

处理GST_MESSAGE_BUFFERING消息,使用gst_message_parse_buffering()处理当前消息,如果小于100设置暂停,如果大于100,设置播放。

First, if this is a live source, ignore buffering messages.

We parse the buffering message with gst_message_parse_buffering() to retrieve the buffering level.

Then, we print the buffering level on the console and set the pipeline to PAUSED if it is below 100%. Otherwise, we set the pipeline to PLAYING.

At startup, we will see the buffering level rise up to 100% before playback starts, which is what we wanted to achieve. If, later on, the network becomes slow or unresponsive and our buffer depletes耗尽, we will receive new buffering messages with levels below 100% so we will pause the pipeline again until enough buffer has been built up.

case GST_MESSAGE_CLOCK_LOST:
  /* Get a new clock */
  gst_element_set_state (data->pipeline, GST_STATE_PAUSED);
  gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
  break;

如果系统时钟丢失,可以通过设置PAUSED和PLAYING来重置时钟。

For the second network issue, the loss of clock, we simply set the pipeline to PAUSED and back to PLAYING, so a new clock is selected, waiting for new media chunks to be received if necessary.

Conclusion

This tutorial has described how to add network resilience弹性 to your application with two very simple precautions防范:

  • Taking care of buffering messages sent by the pipeline
  • Taking care of clock loss

Handling these messages improves the application’s response to network problems, increasing the overall统筹兼顾 playback smoothness平滑.

It has been a pleasure having you here, and see you soon!

【gstreamer】入门介绍 gstreamer 概念介绍 阅读详情

相关推荐

从零开始成为GStreamer专家——基于Windows的GStreamer从源码下载、编译到开发

写一个自己的Hello,Word! 代码下载 一、GStreamer下载 到Sign up · GitLabfreedesktop.org GitLab loginhttps://gitlab.freedesktop.org/users/sign_up上注册一个用户。 在PC机上用ssh-keygen -t rsa -C "yourname@yourhost.com"生成id_rsa.pub值,把这个值贴到下面Key框里,如果这一步不会,请搜索参考ssh-keygen的用法。 git clo...

intel1985的专栏 1万+

Gstreamer基础讲解

gstreamer介绍

qq_37117214的博客 1万+

V4L2与GStreamer实战:从摄像头采集到视频编码的全流程解析

本文详细解析了在Linux环境下,如何利用V4L2框架进行摄像头数据采集,并结合GStreamer多媒体框架完成视频编码与处理的全流程。内容涵盖从设备探查、原始数据捕获,到构建高效管道实现H.264编码、MP4封装,并针对树莓派等嵌入式平台进行硬件编码优化,是嵌入式视频应用开发的实战指南。

weixin_29194693的博客 317

Gstreamer概述

Gstreamer概述

jinking01的专栏 4258

Ubuntu 18.04 RTSP推流实战:GStreamer/VLC/FFmpeg协同调试指南

RTSP(实时流传输协议)是安防、边缘计算和嵌入式视频系统中广泛使用的流媒体信令协议,其核心在于客户端-服务器交互、RTP封装与低延迟传输。理解RTSP与HTTP的本质差异(无状态、不缓存、需主动保活)是解决黑屏、卡顿、连接失败等问题的前提。在Linux平台,GStreamer提供可定制的零拷贝管道能力,VLC承担协议探针与容错调试角色,FFmpeg则作为关键的编解码与协议桥接工具。三者并非替代关系,而是分层协作:GStreamer构建底层流图,VLC验证信令与格式兼容性,FFmpeg处理跨协议转换与SDP

weixin_33794672的博客 425

BurpSuite实战:5分钟搞定Pikachu靶场表单爆破(附最新字典配置技巧)

本文通过Pikachu靶场实战,详细演示了如何使用BurpSuite的Intruder模块对Web登录表单进行暴力破解。从代理配置、请求捕获、集束炸弹模式设置,到载荷配置与结果分析,提供了完整的操作流程。文中还分享了2024年有效的字典获取与优化技巧,帮助安全测试人员快速定位弱口令漏洞。

weixin_29327977的博客 600

【GStreamer 】Basic tutorials-12 Streaming

基础教程14:方便的元素。

qq_43298381的博客 1116

Windows Server 2012 R2虚拟机安装全攻略:从镜像选择到网络配置一步到位

本文提供Windows Server 2012 R2虚拟机安装全攻略,涵盖从镜像选择到网络配置的完整流程。详细讲解在Oracle VM VirtualBox中的安装步骤、TCP/IP网络设置、系统优化及常见问题解决方案,帮助用户快速搭建可立即投入使用的服务器环境。特别适合IT初学者和系统管理员学习传统服务器应用的部署与配置。

weixin_28363123的博客 538

GStreamer——教程——基础教程12:Streaming

在流媒体播放时,媒体数据块解码后立即排队等待呈现。这意味着,如果某个数据块延迟(在互联网上非常常见的情况),则呈现队列可能会耗尽,导致媒体播放停滞。通用解决方案是构建一个“缓冲区”,即允许在开始播放之前将一定数量的媒体数据块排队。这样,虽然播放开始会稍有延迟,但如果某些数据块延迟,由于队列中有更多的数据块等待,播放不会受到影响。事实证明,这个解决方案已经在GStreamer中实现,但之前的教程并没有从中受益。

FREEDOM_X的专栏 1352

基于激光雷达的目标跟随功能移植到自己的ROS机器人小车上

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、下载目标跟随的源码二、修改话题名称1.修改/cmd_vel话题名称2.修改/scan话题名称3.修改双电机正反转4.目标跟随功能测试 前言 本人尝试把github上的一个目标跟随项目移植到自己的机器人小车上,并且成功了,最终小车可以跟着人移动,在这里分享一下心得。基于激光雷达的目标跟随,通过获取激光雷达的信息,跟随最近的物体。 提示:以下是本篇文章正文内容,下面案例可供参考 一、下载目标跟随的源码 源码地址:https:

weixin_44574633的博客 4462

从零实现高精度手势检测:OpenCV+MediaPipe模型移植实战(2)(附c++完整代码)

上篇已经介绍了手掌检测的方法。本章将在手掌检测的基础上,完成手指关节的检测。

qq_37160641的博客 2665

GStreamer Tutorial 中文翻译:Basic tutorial 12: Streaming

GStreamer Tutorial 12中文翻译 文章目录GStreamer Tutorial 12中文翻译前言[Basic tutorial 12: Streaming](https://gstreamer.freedesktop.org/documentation/tutorials/basic/streaming.html?gi-language=c)目的简介一个弹性网络的例子代码走读结论 前言 由于工作原因,用的GStreamer的图像解码库,所以记录GStreamer Tutorial 的中

wuchangwen0216的博客 298

RS485信号测量避坑指南:示波器抓包常见问题与波形分析技巧

本文详细解析了RS485信号测量中的常见问题与解决方案,包括差分信号测量基础、终端电阻配置、共模干扰处理等关键技巧。通过实测波形案例和优化建议,帮助工程师有效提升RS485通信的可靠性和抗干扰能力,适用于工业自动化、远程监测等场景。

kappa的博客 615

GStreamer——教程——播放教程4:Progressive streaming

当流启动,将从互联网获取数据,为了保证流畅的播放,保留了一小块未来数据缓冲区(见基础教程12:流式传输然而,数据将在它被播放或渲染后立即丢弃(程序中不会存在过去的数据缓冲)。这意味着,假如用户想要从过去的某个时刻开始回放,数据需要重新下载。为流媒体量身定制的媒体播放器,例如Youtube,通常将所有下载的数据存储在本地,以防意外情况。通常会使用一个图形窗口来展示当前文件的下载进度。playbin通过DOWNLOAD标记提供了类似的功能,为了更快的播放已下载的数据,playbin。

FREEDOM_X的专栏 959

Spring Boot入门(13):Mybatis-Plus之条件构造器使用手册:精通让你快速提高查询效率的技巧!

化繁为简,MP 中条件构造器的使用,极其详细.

**My Coding Family** 3万+

标题:Stata17安装后遇到Java安装问题解决方法

设置JAVA_HOME环境变量:在Windows上,您需要设置JAVA_HOME环境变量以告诉Stata Java的安装路径。d. 输入变量名为JAVA_HOME,变量值为Java安装路径。注意:请确保您的Java版本与Stata兼容,并使用正确的Java安装路径。设置Stata的Java安装路径:现在,您需要告诉Stata Java的安装路径。如果您看到Java版本信息,则表示Java已成功安装。如果没有安装,请先下载并安装Java。确认Java已安装:首先,请确保您的计算机上已经正确安装了Java。

CyberSparkZ的博客 2867

【Gstreamer 20】播放教程4:渐进式流媒体

Gstreamer 播放教程4:渐进式流媒体

Jayson 博客 895

自私兽群优化器(SHO)详解:从生物本能到智能优化

自私兽群优化器(SHO)是一种受动物群体自私行为启发的智能优化算法。该算法模拟动物在捕食威胁下的两种行为:聚集行为(全局搜索)和自私行为(局部搜索),将优化问题的解空间映射为生存环境,候选解视为猎物个体。SHO通过安全性评估将猎物分为安全、危险和高危三类,分别采用不同的位置更新策略,并引入捕食者角色增加选择压力。相比传统优化算法,SHO具有无需梯度信息、自适应平衡探索与开发、参数简单等优势,特别适合高维复杂和多模态优化问题。算法通过马尔可夫链理论保证收敛性,已在工程设计和数据挖掘等领域展现出良好性能。

qq_42212808的博客 196

GStreamer for Ethernet AVB

GStreamer for Ethernet AVB

汽车以太网和SOA 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

[quote ]ffmpeg, gstreamer, Raspberry Pi, Windows Desktop streaming

[quote ]ffmpeg, gstreamer, Raspberry Pi, Windows Desktop streaming http://blog.pi3g.com/2013/08/ffmpeg-gstreamer-raspberry-pi-windows-desktop-streaming/ This is a work still in progr...

afdd28617的博客 576

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

通过“H.264 RTP Video Streaming”,解析gstreamer 模型 Based on FreescaleImx6&TI

This is one of my end applications of the Overo.  I want to mount this device onto a rover/uav and get real-time streaming, good quality video.  I also didn't want the operation to dominate the CPU.

caibaihui的专栏 7822

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

初探GStreamer .

GStreamer,江湖上人称“PIPELINE式的多媒体处理框架”,在该媒体处理框架将多媒体数据流处理划分成各种能够自由组合重用的节点,然后将 节点组合成串行处理的媒体处理链。看看下面的命令:     gst-launch-0.10 filesrc location="concept.mp3" ! decodebin ! alsasink     UNIX的粉丝们是不是异常眼熟呢?没

pp0xx0ww0的专栏 973

从零开始成为GStreamer专家——MPEG-DASH HLS开发

Gstreamer DASH HLS播放器自主开发

intel1985的专栏 2457

Ubuntu下GStreamer录音播放避坑指南:PulseAudio设备绑定与Caps配置

GStreamer是Linux平台主流的多媒体处理框架,其核心能力依赖于底层音频服务(如PulseAudio或PipeWire)的协同。理解GStreamer Pipeline中src/sink元素与音频后端的绑定机制,是解决无声、爆音、设备识别失败等高频问题的前提。关键在于明确pulsesrc/pulsesink必须显式指定device参数,且需配合capsfilter统一采样率、位深与声道数,再经audioconvert实现格式归一化。该技术路径广泛应用于语音备忘录、会议录制、边缘语音前端等场景,尤其在

weixin_30697239的博客 536

GStreamer中Bin的概念与应用实践

在多媒体处理框架中,容器化设计是构建复杂流水线的关键技术。GStreamer作为开源多媒体框架,通过Bin(箱)概念实现模块化管道设计,其核心原理是将多个处理元素封装为可复用的功能单元。这种设计模式显著提升了媒体处理管道的可维护性和性能表现,特别适用于视频会议、直播推流等实时场景。Bin技术通过幽灵pad实现接口标准化,支持嵌套结构和动态重构,结合队列元素和线程优化可有效降低处理延迟。实际工程中,合理使用Bin容器能简化4K视频处理等复杂管道的调试过程,是GStreamer开发的重要实践方法。

weixin_30294295的博客 426
上一篇: gstreamer基础教程11-Debugging tools
下一篇: gstreamer基础教程13-Playback speed
knowledgebao
博客等级 码龄15年 401粉丝 198原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值