]> git.tdb.fi Git - xinema.git/commitdiff
Export some simple playback information to clients
authorMikko Rasa <tdb@tdb.fi>
Fri, 16 Oct 2015 00:47:37 +0000 (03:47 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 16 Oct 2015 00:47:37 +0000 (03:47 +0300)
source/client.cpp
source/client.h
source/xinema.cpp
source/xinema.h
source/xinestream.cpp
source/xinestream.h

index dbe6091df0f6232c9bfb642663921d7505471297..f116892a06b1073401a5c1683007935f29b9bd97 100644 (file)
@@ -1,7 +1,9 @@
 #include <msp/fs/dir.h>
 #include <msp/fs/stat.h>
+#include <msp/strings/format.h>
 #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;
+       }
+}
index 1f543fc15861f4ebaf2e4cd923e05d38c4d1f37a..fa2ea8d02ebdcfff8002b74e9f8bbb77071d894d 100644 (file)
@@ -1,17 +1,21 @@
 #ifndef CLIENT_H_
 #define CLIENT_H_
 
+#include <sigc++/trackable.h>
 #include <msp/fs/path.h>
 #include <msp/net/streamsocket.h>
+#include <msp/time/timedelta.h>
 
+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
index 025ec562ad85fff87c414f5b023ceeb6cec62eb8..267f6a4eeb42b1dbebce1d71e67fc106133fe397 100644 (file)
@@ -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();
index c54732d464f9dc2be94af01a688ea96c55cc590c..3a2bae178698a742e3608f074247355e6f950609 100644 (file)
@@ -13,6 +13,9 @@ class XineStream;
 
 class Xinema: public Msp::RegisteredApplication<Xinema>
 {
+public:
+       sigc::signal<void, XineStream &> signal_stream_created;
+
 private:
        Msp::Graphics::Display display;
        Msp::Mutex display_mutex;
index 69a0c1f44bdf90e69be4d22e4928af5a21843f3b..d152f518e2cb34941d24521d0e205ed04d532e1e 100644 (file)
@@ -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)
index 642f40534da3b8187867f87fa546b4c51c653435..0b9bbd69462cde16370502a63fe9d4ce6e31611c 100644 (file)
@@ -3,20 +3,31 @@
 
 #include <string>
 #include <xine.h>
+#include <msp/time/timedelta.h>
 
 class XineEngine;
 
 class XineStream
 {
+public:
+       sigc::signal<void, const Msp::Time::TimeDelta &> signal_duration_changed;
+       sigc::signal<void, const Msp::Time::TimeDelta &> 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();