Last active
December 26, 2015 05:59
-
-
Save underdoeg/7104290 to your computer and use it in GitHub Desktop.
gstreamer network sync client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <gst/gst.h> | |
#include <gst/net/gstnet.h> | |
#include <glib.h> | |
#include <sstream> | |
#include <iostream> | |
#include <stdio.h> | |
#include <inetclientstream.hpp> | |
#include <exception.hpp> | |
using namespace std; | |
guint64 toInt(string s) { | |
guint64 res; //number which will contain the result | |
istringstream convert(s); // stringstream used for the conversion constructed with the contents of 'Text' | |
if ( !(convert >> res) ) //give the value to 'Result' using the characters in the stream | |
res = 0; //if that fails set 'Result' to 0 | |
return res; | |
} | |
GstElement* playbin; | |
GstClockTime basetime = 0; | |
GstClockTime lastBasetime = 0; | |
gint64 duration = 0; | |
GstClock* originalClock; | |
GstClock* serverClock; | |
bool isPlaying = false; | |
GstClockTime getServerTime() { | |
using std::string; | |
using libsocket::inet_stream; | |
string host = "127.0.0.1"; | |
string port = "1235"; | |
string answer; | |
answer.resize(32); | |
try { | |
libsocket::inet_stream sock(host, port, LIBSOCKET_IPv4); | |
sock >> answer; | |
sock.destroy(); | |
return toInt(answer); | |
} catch (libsocket::socket_exception exc) { | |
return GST_CLOCK_TIME_NONE; | |
} | |
return GST_CLOCK_TIME_NONE; | |
} | |
void updateServerTime() { | |
GstClockTime basetimeNew = basetime; | |
while(basetimeNew == basetime) { | |
basetimeNew = getServerTime(); | |
} | |
basetime = basetimeNew; | |
if(basetime != GST_CLOCK_TIME_NONE) { | |
gst_element_set_start_time(playbin, GST_CLOCK_TIME_NONE); | |
serverClock = gst_net_client_clock_new(NULL, "127.0.0.1", 1234, basetime); | |
if(serverClock) { | |
gst_pipeline_use_clock(GST_PIPELINE(playbin), serverClock); | |
//gst_element_set_start_time(playbin, basetime); | |
gst_element_set_base_time(playbin, basetime); | |
} | |
} else { | |
gst_pipeline_use_clock(GST_PIPELINE(playbin), originalClock); | |
GstClockTime curTime = gst_clock_get_internal_time(gst_pipeline_get_clock(GST_PIPELINE(playbin))); | |
gst_element_set_base_time(playbin, curTime); | |
} | |
} | |
static gboolean handleMessage (GstBus *bus, GstMessage *msg, void* data) { | |
GError *err; | |
gchar *debug_info; | |
GstClockTime curTime; | |
GstClockTime timeDiff; | |
switch (GST_MESSAGE_TYPE (msg)) { | |
case GST_MESSAGE_ERROR: | |
gst_message_parse_error (msg, &err, &debug_info); | |
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); | |
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); | |
g_clear_error (&err); | |
g_free (debug_info); | |
break; | |
case GST_MESSAGE_EOS: | |
g_print ("End-Of-Stream reached.\n"); | |
/* | |
gint64 len; | |
if (gst_element_query_duration (playbin, GST_FORMAT_BYTES , &len)) { | |
duration = len; | |
cout << duration << endl; | |
} else { | |
cout << "no duration" <<endl; | |
} | |
curTime = gst_clock_get_internal_time(serverClock); | |
timeDiff = curTime - basetime; | |
timeDiff = timeDiff % duration; | |
gst_element_set_base_time(playbin, curTime-timeDiff); | |
*/ | |
//cout << timeDiff << endl; | |
isPlaying = false; | |
gst_element_set_state (playbin, GST_STATE_READY); | |
updateServerTime(); | |
//curTime = gst_clock_get_time(serverClock); | |
//gst_element_set_base_time(playbin, curTime); | |
gst_element_set_state (playbin, GST_STATE_PLAYING); | |
break; | |
case GST_MESSAGE_STATE_CHANGED: | |
GstState old, newState, pending; | |
gst_message_parse_state_changed (msg, &old, &newState, &pending); | |
if (newState == GST_STATE_PLAYING) { | |
if(!isPlaying) { | |
gint64 len; | |
if (gst_element_query_duration (playbin, GST_FORMAT_BYTES , &len)) { | |
duration = len; | |
} | |
isPlaying = true; | |
} | |
} | |
break; | |
default: | |
break; | |
} | |
/* We want to keep receiving messages */ | |
return true; | |
} | |
int main (int argc, char *argv[]) { | |
gst_init (&argc, &argv); | |
playbin = gst_element_factory_make ("playbin", "playbin"); | |
gst_element_set_state (playbin, GST_STATE_READY); | |
g_object_set (playbin, "uri", "file:///home/phwhitfield/videonodesMedia/syncTest/SD1V06H0.MOV.mp4", NULL); | |
GstElement* videosink = gst_element_factory_make("cluttersink", "videosink"); | |
if(videosink) | |
g_object_set(playbin,"video-sink", videosink); | |
else | |
cout << "could not set video sink" << endl; | |
GstBus *bus = gst_element_get_bus (playbin); | |
gst_bus_add_watch (bus, handleMessage, NULL); | |
gst_element_set_state (playbin, GST_STATE_READY); | |
originalClock = gst_pipeline_get_clock(GST_PIPELINE(playbin)); | |
updateServerTime(); | |
//gst_element_set_base_time(playbin, basetime); | |
//gst_element_set_start_time(pipeline, basetime); | |
gst_element_set_state (playbin, GST_STATE_PLAYING); | |
GMainLoop* loop = g_main_loop_new(NULL,FALSE); | |
g_main_loop_run(loop); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment