gstreamer flacenc如何向flac文件添加持续时间信息?
我正在使用gstreamer(gst-launch-1.0版本1.8.3)记录flac文件。命令行如下所示:gstreamer flacenc如何向flac文件添加持续时间信息?,gstreamer,record,flac,Gstreamer,Record,Flac,我正在使用gstreamer(gst-launch-1.0版本1.8.3)记录flac文件。命令行如下所示: gst-launch-1.0 -v alsasrc ! flacenc ! filesink location="output.flac" mediainfo output.flac 上图显示了使用mediainfo的结果 此文件可以在media player上播放,但不支持导航和播放时间。 我认为没有持续时间信息 如何将持续时间信息添加到flac文件中?我认为.flac是一种非常
gst-launch-1.0 -v alsasrc ! flacenc ! filesink location="output.flac"
mediainfo output.flac
上图显示了使用mediainfo的结果
此文件可以在media player上播放,但不支持导航和播放时间。
我认为没有持续时间信息
如何将持续时间信息添加到flac文件中?我认为.flac是一种非常基本的流格式。它不支持随机访问或带有持续时间。除非解析完整的文件,否则无法知道确切的持续时间。有些玩家可能会在这里采取“尽最大努力”的方法,试图大致确定文件的位置,直到你将滑块滑出的位置,但格式本身并没有提供任何东西 我想为了寻找你应该把.flac放进一个像.ogg这样的容器里。这实际上非常类似于.aac文件,它应该放在.mp4中 所以试试
gst-launch-1.0-e-v alsasrc!弗拉森克!oggmux!filesink location=“output.ogg”
我对user199309的答案做了一些修改
编译:g++-o test.c$(pkg-config--cflags--libs-gstreamer-1.0)
#包括
#包括
#定义GLIB\u禁用\u弃用\u警告
静态GstElement*管道;
静态GstPad*队列_src _pad;
静态GstElement*存储箱[2];
静态GstPad*bin_焊盘[2];
静态GstElement*文件链接[2];
静态GMainLoop*循环;
静态GstElement*flacenc[2];
静态大小\u t当前\u bin=0;
静态int当前_文件=0;
静态GSTPADProbe返回
pad_probe_cb(GstPad*pad、GstPadProbeInfo*信息、gpointer用户_数据){
gst_焊盘_移除_探头(焊盘,gst_焊盘_探头_信息_ID(信息));
gst_pad_unlink(队列_src_pad,bin_pad[当前_bin]);
gst_pad_send_事件(bin_pad[当前_bin],gst_事件_new_eos());
gst\u元素\u集合\u状态(bins[当前\u bin],gst\u状态\u NULL);
gst_对象_参考(仓位[当前仓位]);
gst_-bin_移除(gst_-bin(管道)、料仓[当前料仓]);
当前_文件++;
当前\u bin=(当前\u文件%2);
{
字符文件_位置[32];
sprintf(文件位置,“录制%ld.flac”,当前文件);
g_对象集(g_对象(
文件链接[当前位置],“位置”,文件位置,空);
printf(“正在写入%s\n”,文件位置);
}
gst_bin_add(gst_bin(管道),bin[当前_bin]);
gst_pad_链接(队列_src_pad,bin_pad[当前_bin]);
gst元素设置状态(箱子[当前箱子],gst状态播放);
gst元素与父项同步状态(bin[当前bin]);
返回GST\u焊盘\u探头\u正常;
}
静态gboolean超时\u cb(gpointer用户\u数据){
gst\U焊盘\U添加\U探头(队列\U src\U焊盘、gst\U焊盘\U探头\U类型\U块\U下游、,
pad_探头_cb,空,空);
返回TRUE;
}
静态gboolean
总线断路器(GstBus*总线,
GstMessage*msg,
gpointer数据)
{
GMainLoop*循环=(GMainLoop*)数据;
g_打印(“获取%s消息\n”,GST_消息类型_名称(msg));
开关(GST\信息\类型(msg)){
案例GST\信息\ EOS:
g_打印(“流结束\n”);
//g_主循环退出(循环);
打破
案例GST\u消息\u错误:{
gchar*调试;
GError*错误;
gst\消息\解析\错误(消息、错误和调试);
g_自由(调试);
g_printerr(“错误:%s\n”,错误->消息);
g_无错误(错误);
g_主循环退出(循环);
打破
}
违约:
打破
}
返回TRUE;
}
gint干管(gint-argc,gchar*argv[])
{
GstElement*audiosrc;
GstElement*队列;
GstBus*总线;
GMainLoop*循环;
pthread_t libusb_tid;
吉尼特巴士公司;
gst_init(&argc,&argv);
audiosrc=gst元素工厂制造(“ALASRC”、“audiosrc”);
队列=gst元素工厂制造(“队列”、“队列”);
bins[0]=gst_bin_new(“bin0”);
bins[1]=gst_bin_new(“bin1”);
flacenc[0]=商品及服务税(gst)、要素、工厂制造(“flacenc”、“flacenc0”);
flacenc[1]=商品及服务税要素工厂制造(“flacenc”、“flacenc1”);
filesink[0]=gst元素工厂制造(“filesink”、“filesink0”);
filesink[1]=gst元素工厂制造(“filesink”、“filesink1”);
管道=gst_管道_新(“测试管道”);
如果(!pipeline | | |!audiosrc | |!队列
||!flacenc[0]| |!filesink[0]
||!flacenc[1]| |!filesink[1]
) {
g_printerr(“不是所有元素都可以创建\n”);
//返回-1;
}
gst_bin_add_many(gst_bin(bin[0]),flacenc[0],filesink[0],NULL);
gst_-bin_-add_-many(gst_-bin(bin[1]),flacenc[1],filesink[1],NULL);
gst_bin_add_many(gst_bin(管道)、audiosrc、queue、bin[0],NULL);
g_断言(gst_元素链接(audiosrc,queue));
g_assert(gst_元素_链接_许多(flacenc[0],filesink[0],NULL));
g_assert(gst_元素_链接_许多(flacenc[1],filesink[1],NULL));
GstPad*pad=gst_元素_get_静态_pad(flacenc[0],“sink”);
gst_元件_添加_焊盘(箱[0],gst_鬼焊盘_新(“水槽”,焊盘));
商品及服务税(pad);
GstPad*pad2=gst_元件_获取_静态_垫(flacenc[1],“接收器”);
gst_元件添加焊盘(箱[1],gst_鬼焊盘新(“水槽”,焊盘2));
商品及服务税(pad2);
bin_焊盘[0]=gst_元件_获取_静态_焊盘(bin[0],“水槽”);
垃圾桶垫[1]=垃圾桶垫(垃圾桶[1],“水槽”);
当前_bin=0;
gst_元素_链接(队列、箱[当前箱]);
g_对象_集(filesink[current_bin],“location”,“recording_0.flac”,NULL);
queue_src_pad=gst_element_get_static_pad(队列,“src”);
总线=gst\u元件\u获取\u总线(管道);
总线\监视\ id=gst\总线\添加\监视(总线、总线\ cb、环路);
gst元素设置状态(管道、gst状态);
loop=g_main_loop_new(NULL,FALSE);
g\u超时\u添加\u秒(10,超时\u cb,空);
g_主循环运行(循环);
商品及服务税(巴士);
gst\元素\集合\状态(管道,gst\状态\空);
gst_对象_unref(管道);
返回0;
}
谢谢您的回答。使用ffmpeg录制时,存在持续时间字段。命令:ffmpeg-falsa-ac1-ar44100-ihw:1,0output.flacSo可能有一个非正式的met
$ mediainfo output.ogg
General
Complete name : output.ogg
Format : Ogg
Format/Info : Free Lossless Audio Codec
File size : 598 KiB
Duration : 7 s 941 ms
Overall bit rate mode : Variable
Overall bit rate : 617 kb/s
Audio
ID : 256729656 (0xF4D6238)
Format : FLAC
Format/Info : Free Lossless Audio Codec
Duration : 7 s 941 ms
Bit rate mode : Variable
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 44.1 kHz
Bit depth : 16 bits
Writing library : libFLAC 1.3.2 (UTC 2017-01-01)
#include <stdio.h>
#include <gst/gst.h>
#define GLIB_DISABLE_DEPRECATION_WARNINGS
static GstElement *pipeline;
static GstPad *queue_src_pad;
static GstElement *bins[2];
static GstPad *bin_pads[2];
static GstElement *filesink[2];
static GMainLoop *loop;
static GstElement *flacenc[2];
static size_t current_bin = 0;
static int current_file = 0;
static GstPadProbeReturn
pad_probe_cb(GstPad * pad, GstPadProbeInfo * info, gpointer user_data) {
gst_pad_remove_probe(pad, GST_PAD_PROBE_INFO_ID (info));
gst_pad_unlink(queue_src_pad, bin_pads[current_bin]);
gst_pad_send_event(bin_pads[current_bin], gst_event_new_eos());
gst_element_set_state(bins[current_bin], GST_STATE_NULL);
gst_object_ref(bins[current_bin]);
gst_bin_remove(GST_BIN(pipeline), bins[current_bin]);
current_file++;
current_bin = (current_file % 2);
{
char file_location[32];
sprintf(file_location, "recording_%ld.flac", current_file);
g_object_set(G_OBJECT(
filesink[current_bin]), "location", file_location, NULL);
printf("now writing to %s\n", file_location);
}
gst_bin_add(GST_BIN(pipeline), bins[current_bin]);
gst_pad_link(queue_src_pad, bin_pads[current_bin]);
gst_element_set_state(bins[current_bin], GST_STATE_PLAYING);
gst_element_sync_state_with_parent(bins[current_bin]);
return GST_PAD_PROBE_OK;
}
static gboolean timeout_cb(gpointer user_data) {
gst_pad_add_probe(queue_src_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
pad_probe_cb, NULL, NULL);
return TRUE;
}
static gboolean
bus_cb (GstBus *bus,
GstMessage *msg,
gpointer data)
{
GMainLoop *loop = (GMainLoop *)data;
g_print("Got %s message\n", GST_MESSAGE_TYPE_NAME(msg));
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
//g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *error;
gst_message_parse_error(msg, &error, &debug);
g_free(debug);
g_printerr("Error: %s\n", error->message);
g_error_free(error);
g_main_loop_quit(loop);
break;
}
default:
break;
}
return TRUE;
}
gint main(gint argc, gchar *argv[])
{
GstElement *audiosrc;
GstElement *queue;
GstBus *bus;
GMainLoop *loop;
pthread_t libusb_tid;
guint bus_watch_id;
gst_init (&argc, &argv);
audiosrc = gst_element_factory_make("alsasrc", "audiosrc");
queue = gst_element_factory_make("queue", "queue");
bins[0] = gst_bin_new("bin0");
bins[1] = gst_bin_new("bin1");
flacenc[0] = gst_element_factory_make("flacenc", "flacenc0");
flacenc[1] = gst_element_factory_make("flacenc", "flacenc1");
filesink[0] = gst_element_factory_make("filesink", "filesink0");
filesink[1] = gst_element_factory_make("filesink", "filesink1");
pipeline = gst_pipeline_new("test-pipeline");
if (!pipeline || !audiosrc || !queue
|| !flacenc[0] || !filesink[0]
|| !flacenc[1] || !filesink[1]
) {
g_printerr ("not all elements could be created\n");
//return -1;
}
gst_bin_add_many(GST_BIN(bins[0]), flacenc[0], filesink[0], NULL);
gst_bin_add_many(GST_BIN(bins[1]), flacenc[1], filesink[1], NULL);
gst_bin_add_many(GST_BIN(pipeline), audiosrc, queue, bins[0], NULL);
g_assert(gst_element_link(audiosrc, queue));
g_assert(gst_element_link_many(flacenc[0], filesink[0], NULL));
g_assert(gst_element_link_many(flacenc[1], filesink[1], NULL));
GstPad* pad = gst_element_get_static_pad(flacenc[0], "sink");
gst_element_add_pad(bins[0], gst_ghost_pad_new("sink", pad));
gst_object_unref(pad);
GstPad* pad2 = gst_element_get_static_pad(flacenc[1], "sink");
gst_element_add_pad(bins[1], gst_ghost_pad_new("sink", pad2));
gst_object_unref(pad2);
bin_pads[0] = gst_element_get_static_pad(bins[0], "sink");
bin_pads[1] = gst_element_get_static_pad(bins[1], "sink");
current_bin = 0;
gst_element_link(queue, bins[current_bin]);
g_object_set(filesink[current_bin], "location", "recording_0.flac", NULL);
queue_src_pad = gst_element_get_static_pad(queue, "src");
bus = gst_element_get_bus(pipeline);
bus_watch_id = gst_bus_add_watch(bus, bus_cb, loop);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
loop = g_main_loop_new(NULL, FALSE);
g_timeout_add_seconds(10, timeout_cb, NULL);
g_main_loop_run (loop);
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}