From: Mikko Rasa Date: Fri, 16 Oct 2015 00:47:37 +0000 (+0300) Subject: Export some simple playback information to clients X-Git-Url: http://git.tdb.fi/?p=xinema.git;a=commitdiff_plain;h=ed777426d367df15a67082f5dae0911c21472b5f Export some simple playback information to clients --- diff --git a/source/client.cpp b/source/client.cpp index dbe6091..f116892 100644 --- a/source/client.cpp +++ b/source/client.cpp @@ -1,7 +1,9 @@ #include #include +#include #include "client.h" #include "xinema.h" +#include "xinestream.h" using namespace std; using namespace Msp; @@ -13,6 +15,8 @@ Client::Client(Xinema &x, Net::StreamSocket *s): { socket->signal_data_available.connect(sigc::mem_fun(this, &Client::data_available)); socket->signal_end_of_file.connect(sigc::mem_fun(this, &Client::end_of_stream)); + + xinema.signal_stream_created.connect(sigc::mem_fun(this, &Client::stream_created)); } void Client::data_available() @@ -83,3 +87,26 @@ void Client::list_directory(const FS::Path &dn) send_reply("file "+*i); } } + +void Client::stream_created(XineStream &stream) +{ + stream.signal_duration_changed.connect(sigc::mem_fun(this, &Client::stream_duration_changed)); + stream.signal_position_changed.connect(sigc::mem_fun(this, &Client::stream_position_changed)); + string title = stream.get_title(); + if(!title.empty()) + send_reply("title "+title); +} + +void Client::stream_duration_changed(const Time::TimeDelta &dur) +{ + send_reply(format("duration %.3f", dur/Time::sec)); +} + +void Client::stream_position_changed(const Time::TimeDelta &pos) +{ + if(abs(pos-last_position)>=Time::sec) + { + send_reply(format("position %.3f", pos/Time::sec)); + last_position = pos; + } +} diff --git a/source/client.h b/source/client.h index 1f543fc..fa2ea8d 100644 --- a/source/client.h +++ b/source/client.h @@ -1,17 +1,21 @@ #ifndef CLIENT_H_ #define CLIENT_H_ +#include #include #include +#include +class XineStream; class Xinema; -class Client +class Client: public sigc::trackable { private: Xinema &xinema; Msp::Net::StreamSocket *socket; std::string buffer; + Msp::Time::TimeDelta last_position; bool stale; public: @@ -26,6 +30,10 @@ private: void process_command(const std::string &); void send_reply(const std::string &); void list_directory(const Msp::FS::Path &); + + void stream_created(XineStream &); + void stream_duration_changed(const Msp::Time::TimeDelta &); + void stream_position_changed(const Msp::Time::TimeDelta &); }; #endif diff --git a/source/xinema.cpp b/source/xinema.cpp index 025ec56..267f6a4 100644 --- a/source/xinema.cpp +++ b/source/xinema.cpp @@ -36,6 +36,8 @@ int Xinema::main() void Xinema::tick() { + bool new_stream = false; + { MutexLock lock(command_mutex); if(!pending_mrl.empty()) @@ -44,9 +46,13 @@ void Xinema::tick() stream = new XineStream(*engine, pending_mrl); stream->play(); pending_mrl.clear(); + new_stream = true; } } + if(new_stream) + signal_stream_created.emit(*stream); + { MutexLock lock(display_mutex); display.tick(); diff --git a/source/xinema.h b/source/xinema.h index c54732d..3a2bae1 100644 --- a/source/xinema.h +++ b/source/xinema.h @@ -13,6 +13,9 @@ class XineStream; class Xinema: public Msp::RegisteredApplication { +public: + sigc::signal signal_stream_created; + private: Msp::Graphics::Display display; Msp::Mutex display_mutex; diff --git a/source/xinestream.cpp b/source/xinestream.cpp index 69a0c1f..d152f51 100644 --- a/source/xinestream.cpp +++ b/source/xinestream.cpp @@ -25,6 +25,12 @@ XineStream::~XineStream() xine_dispose(stream); } +string XineStream::get_title() const +{ + const char *title = xine_get_meta_info(stream, XINE_META_INFO_TITLE); + return (title ? title : string()); +} + void XineStream::play() { xine_play(stream, 0, 0); @@ -42,6 +48,21 @@ void XineStream::tick() handle_event(*event); xine_event_free(event); } + + int dur_msec, pos_msec; + xine_get_pos_length(stream, 0, &pos_msec, &dur_msec); + Time::TimeDelta dur = dur_msec*Time::msec; + Time::TimeDelta pos = pos_msec*Time::msec; + if(dur!=duration) + { + duration = dur; + signal_duration_changed.emit(duration); + } + if(pos!=position) + { + position = pos; + signal_position_changed.emit(position); + } } void XineStream::handle_event(const xine_event_t &event) diff --git a/source/xinestream.h b/source/xinestream.h index 642f405..0b9bbd6 100644 --- a/source/xinestream.h +++ b/source/xinestream.h @@ -3,20 +3,31 @@ #include #include +#include class XineEngine; class XineStream { +public: + sigc::signal signal_duration_changed; + sigc::signal signal_position_changed; + private: XineEngine &engine; xine_stream_t *stream; xine_event_queue_t *queue; + Msp::Time::TimeDelta duration; + Msp::Time::TimeDelta position; public: XineStream(XineEngine &, const std::string &); ~XineStream(); + const Msp::Time::TimeDelta &get_duration() const { return duration; } + const Msp::Time::TimeDelta &get_position() const { return position; } + std::string get_title() const; + void play(); void stop();