Мне нужно сделать синхронизацию в gstreamer - PullRequest
0 голосов
/ 04 июля 2019

Это мой код для потоковой передачи видео по сети в RTSP. Когда я открываю второй VLC и снова транслирую видео, видео начинается с самого начала, но я хочу, например, выполнить синхронизацию. Первое видео находится на 20-й секунде, второе должно начинаться с 20-й секунды, когда я его открываю. Что я должен сделать, чтобы справиться с синхронизацией.

   #include "pch.h"
   #include <iostream>
   #include <gst/gst.h>
   #include <gst/rtsp-server/rtsp-media.h>
   #include <gst/rtsp-server/rtsp-server.h>
   #include <gst/rtsp-server/rtsp-media-factory-uri.h>
   #include <stdlib.h>
   #include <stdio.h>
   #include <vector>
   #include <stdarg.h>
   #include <stddef.h>
   #include <string.h>
   #define PORT "8554"
   static char *port = (char *)PORT;

    static GOptionEntry entries[] = {
   {"port",'p', 0, G_OPTION_ARG_STRING, &port,"Port " PORT "", "PORT"}, 
   {NULL} };



   int main(int argc, gchar * argv[])
   {
GstElement *pipeline;
GMainLoop *loop;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactoryURI *factory;
GOptionContext *sample;
GError *error = NULL;
gchar *uri;


sample = g_option_context_new("<uri> - Test RTSP Server, URI");
g_option_context_add_main_entries(sample, entries, NULL);
g_option_context_add_group(sample, gst_init_get_option_group());
if (!g_option_context_parse(sample, &argc, &argv, &error)) {
    return -1;
}
loop = g_main_loop_new(NULL, FALSE);

server = gst_rtsp_server_new();
g_object_set(server, "service", port, NULL);

mounts = gst_rtsp_server_get_mount_points(server);

factory = gst_rtsp_media_factory_uri_new();


const char* streamUri = 
   "https://www.freedesktop.org/software/gstreamer- 
   sdk/data/media/sintel_trailer-480p.webm";
pipeline = gst_parse_launch(streamUri,NULL);



if (gst_uri_is_valid(streamUri)) {
    uri = g_strdup(streamUri);
}
else if (g_file_test(streamUri, G_FILE_TEST_EXISTS)) {
    uri = gst_filename_to_uri(streamUri, NULL);
}
else {
    printf("There is no uri");
    return -1;
}

gst_rtsp_media_factory_uri_set_uri(factory, uri);
g_free(uri);

gst_rtsp_mount_points_add_factory(mounts, "/deneme", 
    GST_RTSP_MEDIA_FACTORY(factory));

g_object_unref(mounts);

if (gst_rtsp_server_attach(server, NULL) == 0)
    printf("FAILED!");

g_print("stream ready at rtsp://127.0.0.1:%s/deneme\n", port);



g_main_loop_run(loop);

return 0;

}

1 Ответ

0 голосов
/ 04 июля 2019

вам нужно установить фабрику как расшаренную, вы можете сделать это, вызвав следующую функцию:

/* make the factory shared as we will stream same data */
gst_rtsp_media_factory_set_shared(factory, TRUE);

Вот пример, который я выбрал (https://github.com/freedesktop/gstreamer-gst-rtsp-server/blob/master/examples/), изменено и протестировано

/* GStreamer
 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <gst/gst.h>

#include <gst/rtsp-server/rtsp-server.h>

/* called when a stream has received an RTCP packet from the client */
static void
on_ssrc_active (GObject * session, GObject * source, GstRTSPMedia * media)
{
  GstStructure *stats;

  GST_INFO ("source %p in session %p is active", source, session);

  g_object_get (source, "stats", &stats, NULL);
  if (stats) {
    gchar *sstr;

    sstr = gst_structure_to_string (stats);
    g_print ("structure: %s\n", sstr);
    g_free (sstr);

    gst_structure_free (stats);
  }
}

/* signal callback when the media is prepared for streaming. We can get the
 * session manager for each of the streams and connect to some signals. */
static void
media_prepared_cb (GstRTSPMedia * media)
{
  guint i, n_streams;

  n_streams = gst_rtsp_media_n_streams (media);

  GST_INFO ("media %p is prepared and has %u streams", media, n_streams);

  for (i = 0; i < n_streams; i++) {
    GstRTSPStream *stream;
    GObject *session;

    stream = gst_rtsp_media_get_stream (media, i);
    if (stream == NULL)
      continue;

    session = gst_rtsp_stream_get_rtpsession (stream);
    GST_INFO ("watching session %p on stream %u", session, i);

    g_signal_connect (session, "on-ssrc-active",
        (GCallback) on_ssrc_active, media);
  }
}

static void
media_configure_cb (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
{
  /* connect our prepared signal so that we can see when this media is
   * prepared for streaming */
  g_signal_connect (media, "prepared", (GCallback) media_prepared_cb, factory);
}

int
main (int argc, char *argv[])
{
  GMainLoop *loop;
  GstRTSPServer *server;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory;
  gchar *str;

  gst_init (&argc, &argv);

  if (argc < 2) {
    g_message ("usage: %s <filename.mp4>", argv[0]);
    return -1;
  }

  loop = g_main_loop_new (NULL, FALSE);

  /* create a server instance */
  server = gst_rtsp_server_new ();

  /* get the mount points for this server, every server has a default object
   * that be used to map uri mount points to media factories */
  mounts = gst_rtsp_server_get_mount_points (server);

  str = g_strdup_printf ("( "
      "filesrc location=%s ! qtdemux name=d "
      "d. ! queue ! rtph264pay pt=96 name=pay0 "
      "d. ! queue ! rtpmp4apay pt=97 name=pay1 " ")", argv[1]);

  /* make a media factory for a test stream. The default media factory can use
   * gst-launch syntax to create pipelines. 
   * any launch line works as long as it contains elements named pay%d. Each
   * element with pay%d names will be a stream */
  factory = gst_rtsp_media_factory_new ();
  gst_rtsp_media_factory_set_launch (factory, str);
  g_signal_connect (factory, "media-configure", (GCallback) media_configure_cb,
      factory);
  g_free (str);

  gst_rtsp_media_factory_set_shared(factory, TRUE);
  /* attach the test factory to the /test url */
  gst_rtsp_mount_points_add_factory (mounts, "/test", factory);

  /* don't need the ref to the mapper anymore */
  g_object_unref (mounts);

  /* attach the server to the default maincontext */
  gst_rtsp_server_attach (server, NULL);

  /* start serving */
  g_print ("stream ready at rtsp://127.0.0.1:8554/test\n");
  g_main_loop_run (loop);

  return 0;
}
...