- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想将音频缓冲区写入文件。
问题是文件始终为空或应用程序立即停止并显示内部数据流错误
。
例子是:
https://gist.github.com/nzjrs/725122/16ceee88aafae389bab207818e0661328921e1ab
和
http://gstreamer-devel.966125.n4.nabble.com/appsrc-to-filesink-td970865.html
由他们组成:
#include <string.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
/*
* an example application of using appsrc in push mode to create a video file.
* from buffers we push into the pipeline.
*/
/* Video resolution: 80 x 60 x 4 = 80x60 pixels, 32 bpp (4 bytes per pixel) = 19200 bytes */
#define BUFFER_SIZE 19200
/* 300 frames = 10 seconds of video, since we are going to save at 30fps (se the video_caps next) */
#define TOTAL_FRAMES 30000
#define QUEUED_FRAMES 30
/* these are the caps we are going to pass through the appsrc */
const gchar *video_caps =
"video/x-raw,format=RGB,width=80,height=60,bpp=32,endianness=4321,depth=24,red_mask=65280,green_mask=16711680,blue_mask=-16777216,framerate=30/1";
typedef struct
{
GMainLoop *loop;
GstElement *pipeline;
GstElement *source;
guint source_id;
guint num_frame;
} AppData;
/* This method is called by the idle GSource in the mainloop. We feed 1 buffer
* of BUFFER_SIZE bytes into appsrc.
* The ide handler is added to the mainloop when appsrc requests us to start
* sending data (need-data signal) and is removed when appsrc has enough data
* (enough-data signal).
*/
static gboolean
push_buffer (AppData * app)
{
gpointer raw_buffer;
GstBuffer *app_buffer;
GstMemory *mem;
GstFlowReturn ret;
app->num_frame++;
if (app->num_frame >= TOTAL_FRAMES) {
/* we are EOS, send end-of-stream and remove the source */
g_signal_emit_by_name (app->source, "end-of-stream", &ret);
return FALSE;
}
app_buffer = gst_buffer_new();
mem = gst_allocator_alloc (NULL, BUFFER_SIZE, NULL);
gst_buffer_append_memory(app_buffer, mem);
gst_buffer_set_size(app_buffer, BUFFER_SIZE);
/* Setting the correct timestamp for the buffer is very important, otherwise the
* resulting video file won't be created correctly */
GST_BUFFER_TIMESTAMP(app_buffer) = (GstClockTime)((app->num_frame / 30.0) * 1e9);
/* push new buffer */
g_signal_emit_by_name (app->source, "push-buffer", app_buffer, &ret);
gst_buffer_unref(app_buffer);
if (ret != GST_FLOW_OK) {
/* some error, stop sending data */
return FALSE;
}
return TRUE;
}
/* This signal callback is called when appsrc needs data, we add an idle handler
* to the mainloop to start pushing data into the appsrc */
static void
start_feed (GstElement * pipeline, guint size, AppData * app)
{
if (app->source_id == 0) {
g_print ("start feeding at frame %i\n", app->num_frame);
app->source_id = g_idle_add ((GSourceFunc) push_buffer, app);
}
}
/* This callback is called when appsrc has enough data and we can stop sending.
* We remove the idle handler from the mainloop */
static void
stop_feed (GstElement * pipeline, AppData * app)
{
if (app->source_id != 0) {
g_print ("stop feeding at frame %i\n", app->num_frame);
g_source_remove (app->source_id);
app->source_id = 0;
}
}
/* called when we get a GstMessage from the pipeline when we get EOS, we
* exit the mainloop and this testapp. */
static gboolean
on_pipeline_message (GstBus * bus, GstMessage * message, AppData * app)
{
GstState state, pending;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
g_print ("Received End of Stream message\n");
g_main_loop_quit (app->loop);
break;
case GST_MESSAGE_ERROR:
{
g_print ("Received error\n");
GError *err = NULL;
gchar *dbg_info = NULL;
gst_message_parse_error (message, &err, &dbg_info);
g_printerr ("ERROR from element %s: %s\n",
GST_OBJECT_NAME (message->src), err->message);
g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
g_error_free (err);
g_free (dbg_info);
}
g_main_loop_quit (app->loop);
break;
case GST_MESSAGE_STATE_CHANGED:
gst_element_get_state(app->source, &state, &pending, GST_CLOCK_TIME_NONE);
/* g_print ("State changed from %i to %i\n", state, pending); */
break;
default:
break;
}
return TRUE;
}
int
main (int argc, char *argv[])
{
AppData *app = NULL;
gchar *string = NULL;
GstBus *bus = NULL;
GstElement *appsrc = NULL;
gst_init (&argc, &argv);
app = g_new0 (AppData, 1);
app->loop = g_main_loop_new (NULL, FALSE);
/* setting up pipeline, we push video data into this pipeline that will
* then be recorded to an avi file, encoded with the h.264 codec*/
string =
g_strdup_printf ("appsrc is-live=true name=source caps=\"%s\" ! ffmpegcolorspace ! video/x-raw,format=(fourcc)I420,width=80,height=60 ! queue ! videorate ! video/x-raw,format=YUV,framerate=30/1 ! h264enc ! queue ! avimux ! queue ! filesink location=test.avi",
video_caps);
app->pipeline = gst_parse_launch (string, NULL);
g_free (string);
if (app->pipeline == NULL) {
g_print ("Bad pipeline\n");
return -1;
}
appsrc = gst_bin_get_by_name (GST_BIN (app->pipeline), "source");
/* configure for time-based format */
g_object_set (appsrc, "format", GST_FORMAT_TIME, NULL);
/* setting maximum of bytes queued. default is 200000 */
gst_app_src_set_max_bytes((GstAppSrc *)appsrc, QUEUED_FRAMES * BUFFER_SIZE);
/* uncomment the next line to block when appsrc has buffered enough */
/* g_object_set (appsrc, "block", TRUE, NULL); */
app->source = appsrc;
/* add watch for messages */
bus = gst_element_get_bus (app->pipeline);
gst_bus_add_watch (bus, (GstBusFunc) on_pipeline_message, app);
gst_object_unref (bus);
/* configure the appsrc, we will push data into the appsrc from the
* mainloop */
g_signal_connect (app->source, "need-data", G_CALLBACK (start_feed), app);
g_signal_connect (app->source, "enough-data", G_CALLBACK (stop_feed), app);
/* go to playing and wait in a mainloop */
gst_element_set_state (app->pipeline, GST_STATE_PLAYING);
/* this mainloop is stopped when we receive an error or EOS */
g_print ("Creating movie...\n");
g_main_loop_run (app->loop);
g_print ("Done.\n");
gst_app_src_end_of_stream (GST_APP_SRC (app->source));
gst_element_set_state (app->pipeline, GST_STATE_NULL);
/* Cleaning up */
gst_object_unref (app->source);
gst_object_unref (app->pipeline);
g_main_loop_unref (app->loop);
g_free (app);
return 0;
}
CMakeLists.txt(将FindGStreamer.cmake放入项目的modules/目录):
cmake_minimum_required(VERSION 2.8.11)
project(myproject)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/modules/")
find_package(GStreamer 1.0 REQUIRED COMPONENTS
app
audio
video
)
add_executable(${PROJECT_NAME}
main.c
)
target_include_directories(${PROJECT_NAME} PRIVATE ${GSTREAMER_INCLUDE_DIRS})
target_include_directories(${PROJECT_NAME} PRIVATE ${GSTREAMER_APP_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME}
${GSTREAMER_LIBRARIES}
${GSTREAMER_APP_LIBRARIES}
${GSTREAMER_AUDIO_LIBRARIES}
${GSTREAMER_VIDEO_LIBRARIES}
glib-2.0
gobject-2.0
)
实际上,我的程序的流水线是:
appsrc is-live=true name=mysource ! flacenc ! oggmux ! filesink location=flac-audio.ogg
但我正在努力使示例按原样工作
最佳答案
使用 --gst-debug-level=2
启动很有用。提示 caps
字符串。
#include <string.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
/*
* an example application of using appsrc in push mode to create a file.
* from buffers we push into the pipeline.
*/
/* S16LE 10ms frame audio */
#define BUFFER_SIZE 160
/* 300 frames = 5 minutes */
#define TOTAL_FRAMES 30000
#define QUEUED_FRAMES 30
typedef struct
{
GMainLoop *loop;
GstElement *pipeline;
GstElement *source;
guint source_id;
guint num_frame;
} AppData;
/* This method is called by the idle GSource in the mainloop. We feed 1 buffer
* of BUFFER_SIZE bytes into appsrc.
* The ide handler is added to the mainloop when appsrc requests us to start
* sending data (need-data signal) and is removed when appsrc has enough data
* (enough-data signal).
*/
static gboolean
push_buffer (AppData * app)
{
gpointer raw_buffer;
GstBuffer *app_buffer;
GstMemory *mem;
GstFlowReturn ret;
app->num_frame++;
if (app->num_frame >= TOTAL_FRAMES) {
/* we are EOS, send end-of-stream and remove the source */
g_signal_emit_by_name (app->source, "end-of-stream", &ret);
return FALSE;
}
app_buffer = gst_buffer_new();
mem = gst_allocator_alloc (NULL, BUFFER_SIZE, NULL);
gst_buffer_append_memory(app_buffer, mem);
gst_buffer_set_size(app_buffer, BUFFER_SIZE);
/* Setting the correct timestamp for the buffer is very important, otherwise the
* resulting file won't be created correctly */
GST_BUFFER_TIMESTAMP(app_buffer) = (GstClockTime)((app->num_frame / 100.0) * 1e9);
/* push new buffer */
g_signal_emit_by_name (app->source, "push-buffer", app_buffer, &ret);
gst_buffer_unref(app_buffer);
if (ret != GST_FLOW_OK) {
/* some error, stop sending data */
return FALSE;
}
return TRUE;
}
/* This signal callback is called when appsrc needs data, we add an idle handler
* to the mainloop to start pushing data into the appsrc */
static void
start_feed (GstElement * pipeline, guint size, AppData * app)
{
if (app->source_id == 0) {
g_print ("start feeding at frame %i\n", app->num_frame);
app->source_id = g_idle_add ((GSourceFunc) push_buffer, app);
}
}
/* This callback is called when appsrc has enough data and we can stop sending.
* We remove the idle handler from the mainloop */
static void
stop_feed (GstElement * pipeline, AppData * app)
{
if (app->source_id != 0) {
g_print ("stop feeding at frame %i\n", app->num_frame);
g_source_remove (app->source_id);
app->source_id = 0;
}
}
/* called when we get a GstMessage from the pipeline when we get EOS, we
* exit the mainloop and this testapp. */
static gboolean
on_pipeline_message (GstBus * bus, GstMessage * message, AppData * app)
{
GstState state, pending;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
g_print ("Received End of Stream message\n");
g_main_loop_quit (app->loop);
break;
case GST_MESSAGE_ERROR:
{
g_print ("Received error\n");
GError *err = NULL;
gchar *dbg_info = NULL;
gst_message_parse_error (message, &err, &dbg_info);
g_printerr ("ERROR from element %s: %s\n",
GST_OBJECT_NAME (message->src), err->message);
g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
g_error_free (err);
g_free (dbg_info);
}
g_main_loop_quit (app->loop);
break;
case GST_MESSAGE_STATE_CHANGED:
gst_element_get_state(app->source, &state, &pending, GST_CLOCK_TIME_NONE);
/* g_print ("State changed from %i to %i\n", state, pending); */
break;
default:
break;
}
return TRUE;
}
int
main (int argc, char *argv[])
{
AppData *app = NULL;
GstBus *bus = NULL;
GstElement *appsrc = NULL;
gst_init (&argc, &argv);
app = g_new0 (AppData, 1);
app->loop = g_main_loop_new (NULL, FALSE);
/* setting up pipeline, we push media data into this pipeline that will
* then be recorded to a file, encoded with a codec*/
app->pipeline = gst_parse_launch ("appsrc is-live=true name=source caps=audio/x-raw,format=S16LE,rate=8000,channels=1,layout=interleaved ! flacenc ! oggmux ! filesink location=flac-audio.ogg", NULL);
if (app->pipeline == NULL) {
g_print ("Bad pipeline\n");
return -1;
}
appsrc = gst_bin_get_by_name (GST_BIN (app->pipeline), "source");
/* setting maximum of bytes queued */
gst_app_src_set_max_bytes((GstAppSrc *)appsrc, QUEUED_FRAMES * BUFFER_SIZE);
/* uncomment the next line to block when appsrc has buffered enough */
/* g_object_set (appsrc, "block", TRUE, NULL); */
app->source = appsrc;
/* add watch for messages */
bus = gst_element_get_bus (app->pipeline);
gst_bus_add_watch (bus, (GstBusFunc) on_pipeline_message, app);
gst_object_unref (bus);
/* configure the appsrc, we will push data into the appsrc from the
* mainloop */
g_signal_connect (app->source, "need-data", G_CALLBACK (start_feed), app);
g_signal_connect (app->source, "enough-data", G_CALLBACK (stop_feed), app);
/* go to playing and wait in a mainloop */
gst_element_set_state (app->pipeline, GST_STATE_PLAYING);
/* this mainloop is stopped when we receive an error or EOS */
g_print ("Creating movie...\n");
g_main_loop_run (app->loop);
g_print ("Done.\n");
gst_app_src_end_of_stream (GST_APP_SRC (app->source));
gst_element_set_state (app->pipeline, GST_STATE_NULL);
/* Cleaning up */
gst_object_unref (app->source);
gst_object_unref (app->pipeline);
g_main_loop_unref (app->loop);
g_free (app);
return 0;
}
关于c - GStreamer appsrc 到文件示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42199733/
我正在尝试使用 gstreamer appsrc 通过网络播放视频流。 我在这里找到了很好的例子。 gstreamer appsrc test application http://amarghosh
我正在尝试学习 gstreamer appsrc 插件来从我编写的传输流解复用器播放 AV(我知道插件已经可用,我想自己做来学习)。我已经从 MPEG 传输流中提取了音频和视频基本流;现在我必须将它推
我正在开发一个 C 应用程序(在 Linux 下),它接收原始 h.264 流,并应使用 gstreamer API 可视化该流。我是 GStreamer 的新手,所以也许我犯了巨大的愚蠢错误或忽略了
我正在尝试将 GStreamer appsrc 设置为视频源,但到目前为止,即使是一个微不足道的程序也根本无法运行并且会产生随机崩溃或挂起。你能帮忙发现问题吗?最少的崩溃代码: import gst,
我想将音频缓冲区写入文件。 问题是文件始终为空或应用程序立即停止并显示内部数据流错误。 例子是: https://gist.github.com/nzjrs/725122/16ceee88aafae3
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我是 GStreamer 的新手,以下是我面临的问题 流水线 1 v4l2src device=/dev/video241 !视频/x-h264,高度=720,宽度=1280,帧率=30/1! tvc
这将是我第一次在 C 程序中使用 Gstreamer。我只使用过管道。我正在尝试编写一个程序,该程序将流存储在缓冲区中,使用 OpenCv 编辑流并使用带有 appsrc 的管道来查看流。我收到错误:
我正在尝试使用 GStreamer 呈现文本。文本是我想为视频源的每一帧更新的时间戳。然后,时间戳将覆盖在从 v4l2src 捕获的视频流上。 问题是只有第一个时间戳显示在显示输出中。管道继续运行,调
我正在尝试显示从 UDP 套接字接收到的数据(该数据已经标记为通过 AppSink 的回调) 这是我的代码,应该显示收到的数据: 静态无效gst_native_receive_video_data(J
我的源码主要来自http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/section-data-spoof.html
我有如下层次结构: 源流水线 GstElement 管道(有一个 videotestsrc 和 appsink) 用于推送样本的 GstAppSrc 指针数组 GstRTSP服务器 GstRTSPMe
我正在使用 GStreamer 构建我的第一个应用程序,我的任务是从互联网获取流,使用 CUDA 对其进行修改(更改像素)以并行计算帧,并输出修改后的流。 为简单起见,目前我使用MP4视频读写磁盘,不
我正在开发一个接受 Opencv 帧(源自 opencv camera Api)的应用程序,并在将它们编码为 H264 帧后尝试将这些帧发送到网络中。 对于这个项目,我被要求通过硬件执行编码。 我使用
我正在尝试使用 gstreamer 和icecast 流式传输计算机生成的视频,但我无法让 gstreamer appsrc 工作。如果我使用 xvimagesink 作为接收器,我的应用程序将按预期
我正在使用 appsrc 使用我自己的数据源实现 gstreamer 媒体播放器。一切正常,除了一件事: 当流到达它的末尾时,回调发出 "end-of-stream" 信号。信号发送函数 g_sign
我正在尝试通过 rtmp 流式传输我的网络摄像头。我尝试通过以下管道流式传输数据: gst-launch-1.0 -v v4l2src ! 'video/x-raw, width=640, heigh
我正在尝试打开一个 mp4 视频,对其进行解码并将其发送到 appsink。然后从 appsrc 接收它并将其保存在 mp4 文件中。 我确信我设置的上限是错误的。 const gchar *vide
我是一名优秀的程序员,十分优秀!