欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > GStreamer —— 2.13、Windows下Qt加载GStreamer库后运行 - “教程13:播放控制“(附:完整源码)

GStreamer —— 2.13、Windows下Qt加载GStreamer库后运行 - “教程13:播放控制“(附:完整源码)

2025/4/2 2:23:29 来源:https://blog.csdn.net/automoblie0/article/details/146098980  浏览:    关键词:GStreamer —— 2.13、Windows下Qt加载GStreamer库后运行 - “教程13:播放控制“(附:完整源码)
运行效果(音频)

请添加图片描述

简介

     上一个教程演示了GStreamer工具。本教程介绍视频播放控制。快进、反向播放和慢动作都是技术 统称为 Trick Modes,它们都有一个共同点 修改 Normal playback rate。本教程介绍如何实现 这些效果并在交易中添加了帧步进。特别是,它 显示:

          • 如何更改播放速率,比正常更快和更慢, 前进和向后。

          • 如何逐帧推进视频

     快进是一种以高于 它的正常(预期)速度;而慢动作使用低于 预期的那个。反向播放执行相同的作,但向后播放, 从流的结尾到开头。所有这些技术所做的只是更改播放速率,这是一个变量 等于 1.0 表示正常播放,大于 1.0(绝对值) 对于快速模式,对于慢速模式,低于 1.0(绝对值), positive 表示正向播放,negative 表示反向播放。GStreamer 提供了两种机制来更改播放速率:步进 事件 (Events) 和查找事件 (Seek Events)。Step Events 允许跳过给定数量的 媒体,除了更改后续播放速率(仅为正数 值)。此外,Seek Events 还允许跳转到 流式传输并设置正播放速率和负播放速率。

GStreamer相关运行库
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/gstreamer-1.0/gst
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/gstreamer-1.0
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/glib-2.0
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/lib/glib-2.0/includeLIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gstreamer-1.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/glib-2.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gobject-2.0.lib

完整源码
#include <string.h>
#include <stdio.h>
#include <gst/gst.h>#ifdef __APPLE__
#include <TargetConditionals.h>
#endiftypedef struct _CustomData
{GstElement *pipeline;GstElement *video_sink;GMainLoop *loop;gboolean playing;             /* 播放或暂停 */gdouble rate;                 /* 当前播放速率(可以为负) */
} CustomData;/* Send seek event to change rate */
static void
send_seek_event (CustomData * data)
{gint64 position;GstEvent *seek_event;/* Obtain the current position, needed for the seek event */if (!gst_element_query_position (data->pipeline, GST_FORMAT_TIME, &position)) {g_printerr ("Unable to retrieve current position.\n");return;}/* Create the seek event */if (data->rate > 0) {seek_event =gst_event_new_seek (data->rate, GST_FORMAT_TIME,(GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), GST_SEEK_TYPE_SET,position, GST_SEEK_TYPE_END, 0);} else {seek_event =gst_event_new_seek (data->rate, GST_FORMAT_TIME,GstSeekFlags(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), GST_SEEK_TYPE_SET, 0,GST_SEEK_TYPE_SET, position);}if (data->video_sink == NULL) {/* If we have not done so, obtain the sink through which we will send the seek events */g_object_get (data->pipeline, "video-sink", &data->video_sink, NULL);}/* Send the event */gst_element_send_event (data->video_sink, seek_event);g_print ("Current rate: %g\n", data->rate);
}/* 处理键盘输入 */
static gboolean
handle_keyboard (GIOChannel * source, GIOCondition cond, CustomData * data)
{gchar *str = NULL;if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) { return TRUE; }switch (g_ascii_tolower (str[0])){case 'p':data->playing = !data->playing;gst_element_set_state (data->pipeline, data->playing ? GST_STATE_PLAYING : GST_STATE_PAUSED);g_print ("Setting state to %s\n", data->playing ? "PLAYING" : "PAUSE"); break;case 's':if (g_ascii_isupper (str[0])){data->rate *= 2.0;}else{data->rate /= 2.0;}send_seek_event (data); break;case 'd':data->rate *= -1.0; send_seek_event (data);  break;case 'n':if (data->video_sink == NULL){/* If we have not done so, obtain the sink through which we will send the step events */g_object_get (data->pipeline, "video-sink", &data->video_sink, NULL);}gst_element_send_event (data->video_sink,gst_event_new_step (GST_FORMAT_BUFFERS, 1, ABS (data->rate), TRUE,FALSE));g_print ("Stepping one frame\n");break;case 'q':g_main_loop_quit (data->loop);break;default:break;}g_free (str);return TRUE;
}int tutorial_main (int argc, char *argv[])
{/* 初始化GStreamer */gst_init (&argc, &argv);/* 初始化自定义数据 */CustomData data;memset (&data, 0, sizeof (data));/* 输出使用方式 */g_print ("USAGE: Choose one of the following options, then press enter:\n"" 'P' to toggle between PAUSE and PLAY\n"" 'S' to increase playback speed, 's' to decrease playback speed\n"" 'D' to toggle playback direction\n"" 'N' to move to next frame (in the current direction, better in PAUSE)\n"" 'Q' to quit\n");/* 构建管道 */data.pipeline =gst_parse_launch("playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm", NULL);/* 增加键盘输入以进行控制 */
#ifdef G_OS_WIN32GIOChannel *io_stdin = g_io_channel_win32_new_fd (fileno (stdin));
#elseGIOChannel *io_stdin = g_io_channel_unix_new (fileno (stdin));
#endifg_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, &data);/* 开始播放 */GstStateChangeReturn ret = gst_element_set_state (data.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 (data.pipeline); return -1;}data.playing = TRUE;data.rate = 1.0;/* 创建GLib主循环并将其设置为运行 */data.loop = g_main_loop_new (NULL, FALSE);g_main_loop_run (data.loop);/* 释放资源 */g_main_loop_unref (data.loop);g_io_channel_unref (io_stdin);gst_element_set_state (data.pipeline, GST_STATE_NULL);if (data.video_sink != NULL)gst_object_unref (data.video_sink);gst_object_unref (data.pipeline);return 0;
}int main (int argc, char *argv[])
{
#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONEreturn gst_macos_main ((GstMainFunc) tutorial_main, argc, argv, NULL);
#elsereturn tutorial_main (argc, argv);
#endif
}

关注

笔者 - jxd

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词