[rygel] renderer: Turn PlayerController into an interface
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] renderer: Turn PlayerController into an interface
- Date: Tue, 19 Aug 2014 19:36:54 +0000 (UTC)
commit ac922555b81299f86ec405f6d54fb843002f8f58
Author: Richard Röjfors <richard rojfors gmail com>
Date: Sun Jun 22 19:36:19 2014 +0200
renderer: Turn PlayerController into an interface
There is a need to be able to reimplement the rygel-player-controller
By changing the class to become an interface, other classes can
implement it.
The current implementation is moved to a default controller.
This controller is instantiated by get_controller of the plugin as
before, but now the get_controller function is defined virtual.
Making it possible for plugins to reimplement and return another
controller.
Signed-off-by: Richard Röjfors <richard rojfors gmail com>
https://bugzilla.gnome.org/show_bug.cgi?id=732057
src/librygel-renderer/filelist.am | 5 +-
.../rygel-default-player-controller.vala | 417 ++++++++++++++++++++
.../rygel-media-renderer-plugin.vala | 4 +-
src/librygel-renderer/rygel-player-controller.vala | 378 ++-----------------
4 files changed, 445 insertions(+), 359 deletions(-)
---
diff --git a/src/librygel-renderer/filelist.am b/src/librygel-renderer/filelist.am
index 3f5cb08..d5e68a0 100644
--- a/src/librygel-renderer/filelist.am
+++ b/src/librygel-renderer/filelist.am
@@ -1,11 +1,12 @@
LIBRYGEL_RENDERER_VAPI_SOURCE_FILES = \
rygel-media-renderer-plugin.vala \
rygel-media-player.vala \
- rygel-media-renderer.vala
+ rygel-media-renderer.vala \
+ rygel-player-controller.vala
LIBRYGEL_RENDERER_NONVAPI_SOURCE_FILES = \
rygel-av-transport.vala \
- rygel-player-controller.vala \
+ rygel-default-player-controller.vala \
rygel-rendering-control.vala \
rygel-sink-connection-manager.vala \
rygel-time-utils.vala \
diff --git a/src/librygel-renderer/rygel-default-player-controller.vala
b/src/librygel-renderer/rygel-default-player-controller.vala
new file mode 100644
index 0000000..93ff541
--- /dev/null
+++ b/src/librygel-renderer/rygel-default-player-controller.vala
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2014 Atlantic PuffinPack AB.
+ *
+ * Author: Richard Röjfors <richard puffinpack se>
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using GUPnP;
+
+/**
+ * This class keeps track of global states that are not dependant on the
+ * RygelMediaPlayer.
+ *
+ * These states are:
+ * # URI
+ * # MetaData
+ * # Number of tracks
+ * # Current track
+ * # Playback state
+ *
+ * In case of playlists this class will also control the player. It needs to
+ * proxy the playback state to react on end of item to be able to switch to
+ * the next item.
+ */
+internal class Rygel.DefaultPlayerController : Rygel.PlayerController, Object {
+ private const int DEFAULT_IMAGE_TIMEOUT = 15;
+ private const string CONFIG_SECTION = "Renderer";
+ private const string TIMEOUT_KEY = "image-timeout";
+ private const string DIDL_FRAME_TEMPLATE = "<DIDL-Lite " +
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " +
+ "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " +
+ "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " +
+ "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" +
+ "%s</DIDL-Lite>";
+
+ /* private (construction) properties */
+ public MediaPlayer player { construct; private get; }
+ public string protocol_info { construct; private get; }
+
+ /* public properties */
+
+ /* this._playback_state mirrors player.playback_state without including
+ * non-UPnP "EOS" value. It is updated from notify_state_cb */
+ [CCode (notify = false)]
+ public string playback_state {
+ get { return this._playback_state; }
+ set { this.player.playback_state = value; }
+ }
+
+ [CCode (notify = false)]
+ public uint n_tracks {
+ get { return this._n_tracks; }
+ private set {
+ if (value != this._n_tracks) {
+ this._n_tracks = value;
+ this.notify_property ("n-tracks");
+ }
+ }
+ default = 0;
+ }
+
+ [CCode (notify = false)]
+ public uint track {
+ get { return this._track; }
+ set {
+ if (value != this._track) {
+ this._track = value;
+ this.apply_track ();
+ this.notify_property ("track");
+ }
+ }
+ default = 0;
+ }
+
+ public string uri { owned get; private set; default = ""; }
+ public string metadata { owned get; private set; default = ""; }
+
+ [CCode (notify = false)]
+ public string track_uri {
+ owned get {
+ if (this.player.uri != null) {
+ return Markup.escape_text (this.player.uri);
+ } else {
+ return "";
+ }
+ }
+
+ private set {
+ this.player.uri = value;
+ }
+ }
+
+ [CCode (notify = false)]
+ public string track_metadata {
+ owned get { return this.player.metadata ?? ""; }
+
+ private set {
+ if (value.has_prefix ("<")) {
+ this.player.metadata = this.unescape (value);
+ } else {
+ this.player.metadata = value;
+ }
+ }
+ }
+
+ public string next_uri { owned get; private set; default = ""; }
+ public string next_metadata { owned get; private set; default = ""; }
+
+ public string current_transport_actions {
+ owned get {
+ string actions = null;
+ switch (this.playback_state) {
+ case "PLAYING":
+ case "TRANSITIONING":
+ actions = "Stop,Seek,Pause";
+ break;
+ case "STOPPED":
+ actions = "Play";
+ break;
+ case "PAUSED_PLAYBACK":
+ actions = "Stop,Play,Seek";
+ break;
+ default:
+ break;
+ }
+
+ if (actions == null) {
+ return "";
+ }
+
+ if (this.track < this.n_tracks) {
+ actions += ",Next";
+ }
+ if (this.track > 1) {
+ actions += ",Previous";
+ }
+
+ if (this.player.can_seek) {
+ actions += ",X_DLNA_SeekTime";
+ }
+ if (actions != null && this.player.can_seek_bytes) {
+ actions += ",X_DLNA_SeekByte";
+ }
+
+ if (actions != null &&
+ this.player.allowed_playback_speeds.length > 1) {
+ string play_speeds = "";
+ foreach (var speed in this.player.allowed_playback_speeds) {
+ if (speed != "1") {
+ if (play_speeds == "") {
+ play_speeds = ",X_DLNA_PS=" + speed;
+ } else {
+ play_speeds += "\\," + speed;
+ }
+ }
+ }
+ actions += play_speeds;
+ }
+
+ return actions;
+ }
+ }
+
+ // Private members
+ private List<DIDLLiteItem> playlist;
+ private uint timeout_id;
+ private uint default_image_timeout;
+ private Configuration config;
+
+ private string next_features;
+ private string next_mime;
+ private MediaCollection next_collection;
+
+ // Private property variables
+ private uint _n_tracks;
+ private uint _track;
+ private string _playback_state = "NO_MEDIA_PRESENT";
+
+ public DefaultPlayerController (MediaPlayer player, string protocol_info) {
+ Object (player : player, protocol_info : protocol_info);
+ }
+
+ public override void constructed () {
+ base.constructed ();
+
+ this.player.notify["playback-state"].connect (this.notify_state_cb);
+ this.player.notify["uri"].connect (this.notify_uri_cb);
+ this.player.notify["metadata"].connect (this.notify_metadata_cb);
+
+ this.config = MetaConfig.get_default ();
+ this.config.setting_changed.connect (this.on_setting_changed);
+ this.default_image_timeout = DEFAULT_IMAGE_TIMEOUT;
+ this.on_setting_changed (CONFIG_SECTION, TIMEOUT_KEY);
+ }
+
+ public bool next () {
+ // Try advancing in playlist
+ if (this.track < this.n_tracks) {
+ this.track++;
+
+ return true;
+ }
+
+ // Try playing next_uri
+ if (this.next_uri != "") {
+ if (this.next_collection != null) {
+ this.set_playlist_uri (this.next_uri,
+ this.next_metadata,
+ this.next_collection);
+ } else {
+ this.set_single_play_uri (this.next_uri,
+ this.next_metadata,
+ this.next_mime,
+ this.next_features);
+ }
+
+ this.next_uri = "";
+ this.next_metadata = "";
+ this.next_mime = null;
+ this.next_features = null;
+ this.next_collection = null;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool previous () {
+ if (this.track <= 1) {
+ return false;
+ }
+
+ this.track--;
+
+ return true;
+ }
+
+ public void set_single_play_uri (string uri,
+ string metadata,
+ string? mime,
+ string? features)
+ {
+ if (this.timeout_id != 0) {
+ Source.remove (this.timeout_id);
+ this.timeout_id = 0;
+ }
+
+ this.metadata = this.unescape (metadata);
+ this.uri = uri;
+
+ this.player.mime_type = mime ?? "";
+ this.player.content_features = features ?? "*";
+
+ this.track_metadata = this.metadata;
+ this.track_uri = this.uri;
+
+ this.playlist = null;
+
+ if (this.uri == "") {
+ this.n_tracks = 0;
+ this.track = 0;
+ } else {
+ this.n_tracks = 1;
+ this.track = 1;
+ }
+ }
+
+ public void set_playlist_uri (string uri,
+ string metadata,
+ MediaCollection collection) {
+ if (this.timeout_id != 0) {
+ Source.remove (this.timeout_id);
+ this.timeout_id = 0;
+ }
+
+ this.metadata = this.unescape (metadata);
+ this.uri = uri;
+
+ this.playlist = collection.get_items ();
+ this.n_tracks = this.playlist.length ();
+
+ // bypass track setter: we want to run apply_track()
+ // even if track value does not change
+ var need_notify = (this.track != 1);
+ this._track = 1;
+ this.apply_track ();
+ if (need_notify) {
+ this.notify_property ("track");
+ }
+ }
+
+ public void set_next_single_play_uri (string uri,
+ string metadata,
+ string? mime,
+ string? features) {
+ this.next_uri = uri;
+ this.next_metadata = metadata;
+ this.next_mime = mime;
+ this.next_features = features;
+ this.next_collection = null;
+ }
+
+ public void set_next_playlist_uri (string uri,
+ string metadata,
+ MediaCollection collection) {
+ this.next_uri = uri;
+ this.next_metadata = metadata;
+ this.next_mime = null;
+ this.next_features = null;
+ this.next_collection = collection;
+ }
+
+ private void notify_state_cb (Object player, ParamSpec p) {
+ var state = this.player.playback_state;
+ if (state == "EOS") {
+ // Play next item in playlist, play next_uri, or move to STOPPED
+ Idle.add (() => {
+ if (!this.next ()) {
+ this.reset ();
+ }
+
+ return false;
+ });
+ } else if (this._playback_state != state) {
+ // mirror player value in _playback_state and notify
+ this._playback_state = state;
+ this.notify_property ("playback-state");
+ }
+ }
+
+ private void notify_uri_cb (Object player, ParamSpec p) {
+ notify_property ("track-uri");
+ }
+
+ private void notify_metadata_cb (Object player, ParamSpec p) {
+ notify_property ("track-metadata");
+ }
+
+ private void apply_track () {
+ // We only have something to do here if we have playlist items
+ if (this.playlist != null) {
+ var item = this.playlist.nth (this.track - 1).data;
+
+ var res = item.get_compat_resource (this.protocol_info, true);
+ this.track_metadata = DIDL_FRAME_TEMPLATE.printf
+ (item.get_xml_string ());
+ this.track_uri = res.get_uri ();
+
+ if (item.upnp_class.has_prefix ("object.item.image") &&
+ this.playback_state != "STOPPED") {
+ this.setup_image_timeouts (item.lifetime);
+ }
+ }
+ }
+
+ private void reset () {
+ this.playback_state = "STOPPED";
+ this.track = 1;
+ }
+
+ private void setup_image_timeouts (long lifetime) {
+ // For images, we handle the timeout here. Either the item carries a
+ // dlna:lifetime tag, then we use that or we use a default timeout of
+ // 5 minutes.
+ var timeout = this.default_image_timeout;
+ if (lifetime > 0) {
+ timeout = (uint) lifetime;
+ }
+
+ debug ("Item is image, setup timer: %ld", timeout);
+
+ if (this.timeout_id != 0) {
+ Source.remove (this.timeout_id);
+ }
+
+ this.timeout_id = Timeout.add_seconds ((uint) timeout, () => {
+ this.timeout_id = 0;
+ if (!this.next ()) {
+ this.reset ();
+ }
+
+ return false;
+ });
+ }
+
+ private void on_setting_changed (string section, string key) {
+ if (section != CONFIG_SECTION && key != TIMEOUT_KEY) {
+ return;
+ }
+
+ try {
+ this.default_image_timeout = config.get_int (CONFIG_SECTION,
+ TIMEOUT_KEY,
+ 0,
+ int.MAX);
+ } catch (Error error) {
+ this.default_image_timeout = DEFAULT_IMAGE_TIMEOUT;
+ }
+
+ debug ("New image timeout: %lu", this.default_image_timeout);
+ }
+}
diff --git a/src/librygel-renderer/rygel-media-renderer-plugin.vala
b/src/librygel-renderer/rygel-media-renderer-plugin.vala
index 4d27406..fd0c795 100644
--- a/src/librygel-renderer/rygel-media-renderer-plugin.vala
+++ b/src/librygel-renderer/rygel-media-renderer-plugin.vala
@@ -107,9 +107,9 @@ public class Rygel.MediaRendererPlugin : Rygel.Plugin {
return null;
}
- internal PlayerController get_controller () {
+ internal virtual PlayerController get_controller () {
if (this.controller == null) {
- this.controller = new PlayerController (this.get_player (),
+ this.controller = new DefaultPlayerController (this.get_player (),
this.get_protocol_info ());
}
diff --git a/src/librygel-renderer/rygel-player-controller.vala
b/src/librygel-renderer/rygel-player-controller.vala
index 24f8469..93f5a36 100644
--- a/src/librygel-renderer/rygel-player-controller.vala
+++ b/src/librygel-renderer/rygel-player-controller.vala
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2014 Atlantic PuffinPack AB.
*
* Author: Jens Georg <jensg openismus com>
*
@@ -35,386 +36,53 @@ using GUPnP;
* proxy the playback state to react on end of item to be able to switch to
* the next item.
*/
-internal class Rygel.PlayerController : Object {
- private const int DEFAULT_IMAGE_TIMEOUT = 15;
- private const string CONFIG_SECTION = "Renderer";
- private const string TIMEOUT_KEY = "image-timeout";
- private const string DIDL_FRAME_TEMPLATE = "<DIDL-Lite " +
- "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " +
- "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " +
- "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " +
- "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" +
- "%s</DIDL-Lite>";
-
- /* private (construction) properties */
- public MediaPlayer player { construct; private get; }
- public string protocol_info { construct; private get; }
+public interface Rygel.PlayerController : GLib.Object {
/* public properties */
/* this._playback_state mirrors player.playback_state without including
* non-UPnP "EOS" value. It is updated from notify_state_cb */
- [CCode (notify = false)]
- public string playback_state {
- get { return this._playback_state; }
- set { this.player.playback_state = value; }
- }
-
- [CCode (notify = false)]
- public uint n_tracks {
- get { return this._n_tracks; }
- private set {
- if (value != this._n_tracks) {
- this._n_tracks = value;
- this.notify_property ("n-tracks");
- }
- }
- default = 0;
- }
-
- [CCode (notify = false)]
- public uint track {
- get { return this._track; }
- set {
- if (value != this._track) {
- this._track = value;
- this.apply_track ();
- this.notify_property ("track");
- }
- }
- default = 0;
- }
-
- public string uri { get; private set; default = ""; }
- public string metadata { get; private set; default = ""; }
-
- [CCode (notify = false)]
- public string track_uri {
- owned get {
- if (this.player.uri != null) {
- return Markup.escape_text (this.player.uri);
- } else {
- return "";
- }
- }
-
- private set {
- this.player.uri = value;
- }
- }
-
- [CCode (notify = false)]
- public string track_metadata {
- owned get { return this.player.metadata ?? ""; }
-
- private set {
- if (value.has_prefix ("<")) {
- this.player.metadata = this.unescape (value);
- } else {
- this.player.metadata = value;
- }
- }
- }
-
- public string next_uri { get; private set; default = ""; }
- public string next_metadata { get; private set; default = ""; }
-
- public string current_transport_actions {
- owned get {
- string actions = null;
- switch (this.playback_state) {
- case "PLAYING":
- case "TRANSITIONING":
- actions = "Stop,Seek,Pause";
- break;
- case "STOPPED":
- actions = "Play";
- break;
- case "PAUSED_PLAYBACK":
- actions = "Stop,Play,Seek";
- break;
- default:
- break;
- }
-
- if (actions == null) {
- return "";
- }
-
- if (this.track < this.n_tracks) {
- actions += ",Next";
- }
- if (this.track > 1) {
- actions += ",Previous";
- }
+ public abstract string playback_state { get; set; }
- if (this.player.can_seek) {
- actions += ",X_DLNA_SeekTime";
- }
- if (actions != null && this.player.can_seek_bytes) {
- actions += ",X_DLNA_SeekByte";
- }
+ public abstract uint n_tracks { get; protected set; }
- if (actions != null &&
- this.player.allowed_playback_speeds.length > 1) {
- string play_speeds = "";
- foreach (var speed in this.player.allowed_playback_speeds) {
- if (speed != "1") {
- if (play_speeds == "") {
- play_speeds = ",X_DLNA_PS=" + speed;
- } else {
- play_speeds += "\\," + speed;
- }
- }
- }
- actions += play_speeds;
- }
+ public abstract uint track { get; set; }
- return actions;
- }
- }
-
- // Private members
- private List<DIDLLiteItem> playlist;
- private uint timeout_id;
- private uint default_image_timeout;
- private Configuration config;
-
- private string next_features;
- private string next_mime;
- private MediaCollection next_collection;
+ public abstract string uri { owned get; protected set; }
+ public abstract string metadata { owned get; protected set; }
- // Private property variables
- private uint _n_tracks;
- private uint _track;
- private string _playback_state = "NO_MEDIA_PRESENT";
-
- public PlayerController (MediaPlayer player, string protocol_info) {
- Object (player : player, protocol_info : protocol_info);
- }
-
- public override void constructed () {
- base.constructed ();
-
- this.player.notify["playback-state"].connect (this.notify_state_cb);
- this.player.notify["uri"].connect (this.notify_uri_cb);
- this.player.notify["metadata"].connect (this.notify_metadata_cb);
-
- this.config = MetaConfig.get_default ();
- this.config.setting_changed.connect (this.on_setting_changed);
- this.default_image_timeout = DEFAULT_IMAGE_TIMEOUT;
- this.on_setting_changed (CONFIG_SECTION, TIMEOUT_KEY);
- }
+ public abstract string track_uri { owned get; protected set; }
- public bool next () {
- // Try advancing in playlist
- if (this.track < this.n_tracks) {
- this.track++;
+ public abstract string track_metadata { owned get; protected set; }
- return true;
- }
+ public abstract string next_uri { owned get; protected set; }
+ public abstract string next_metadata { owned get; protected set; }
- // Try playing next_uri
- if (this.next_uri != "") {
- if (this.next_collection != null) {
- this.set_playlist_uri (this.next_uri,
- this.next_metadata,
- this.next_collection);
- } else {
- this.set_single_play_uri (this.next_uri,
- this.next_metadata,
- this.next_mime,
- this.next_features);
- }
+ public abstract string current_transport_actions { owned get; }
- this.next_uri = "";
- this.next_metadata = "";
- this.next_mime = null;
- this.next_features = null;
- this.next_collection = null;
+ public abstract bool next ();
- return true;
- }
+ public abstract bool previous ();
- return false;
- }
-
- public bool previous () {
- if (this.track <= 1) {
- return false;
- }
-
- this.track--;
-
- return true;
- }
-
- public void set_single_play_uri (string uri,
+ public abstract void set_single_play_uri (string uri,
string metadata,
string? mime,
- string? features)
- {
- if (this.timeout_id != 0) {
- Source.remove (this.timeout_id);
- this.timeout_id = 0;
- }
-
- this.metadata = this.unescape (metadata);
- this.uri = uri;
-
- this.player.mime_type = mime ?? "";
- this.player.content_features = features ?? "*";
+ string? features);
- this.track_metadata = this.metadata;
- this.track_uri = this.uri;
-
- this.playlist = null;
-
- if (this.uri == "") {
- this.n_tracks = 0;
- this.track = 0;
- } else {
- this.n_tracks = 1;
- this.track = 1;
- }
- }
-
- public void set_playlist_uri (string uri,
+ public abstract void set_playlist_uri (string uri,
string metadata,
- MediaCollection collection) {
- if (this.timeout_id != 0) {
- Source.remove (this.timeout_id);
- this.timeout_id = 0;
- }
-
- this.metadata = this.unescape (metadata);
- this.uri = uri;
+ MediaCollection collection);
- this.playlist = collection.get_items ();
- this.n_tracks = this.playlist.length ();
-
- // bypass track setter: we want to run apply_track()
- // even if track value does not change
- var need_notify = (this.track != 1);
- this._track = 1;
- this.apply_track ();
- if (need_notify) {
- this.notify_property ("track");
- }
- }
-
- public void set_next_single_play_uri (string uri,
+ public abstract void set_next_single_play_uri (string uri,
string metadata,
string? mime,
- string? features) {
- this.next_uri = uri;
- this.next_metadata = metadata;
- this.next_mime = mime;
- this.next_features = features;
- this.next_collection = null;
- }
+ string? features);
- public void set_next_playlist_uri (string uri,
+ public abstract void set_next_playlist_uri (string uri,
string metadata,
- MediaCollection collection) {
- this.next_uri = uri;
- this.next_metadata = metadata;
- this.next_mime = null;
- this.next_features = null;
- this.next_collection = collection;
- }
-
- private void notify_state_cb (Object player, ParamSpec p) {
- var state = this.player.playback_state;
- if (state == "EOS") {
- // Play next item in playlist, play next_uri, or move to STOPPED
- Idle.add (() => {
- if (!this.next ()) {
- this.reset ();
- }
-
- return false;
- });
- } else if (this._playback_state != state) {
- // mirror player value in _playback_state and notify
- this._playback_state = state;
- this.notify_property ("playback-state");
- }
- }
-
- private void notify_uri_cb (Object player, ParamSpec p) {
- notify_property ("track-uri");
- }
-
- private void notify_metadata_cb (Object player, ParamSpec p) {
- notify_property ("track-metadata");
- }
-
- private void apply_track () {
- // We only have something to do here if we have playlist items
- if (this.playlist != null) {
- var item = this.playlist.nth (this.track - 1).data;
-
- var res = item.get_compat_resource (this.protocol_info, true);
- this.track_metadata = DIDL_FRAME_TEMPLATE.printf
- (item.get_xml_string ());
- this.track_uri = res.get_uri ();
-
- if (item.upnp_class.has_prefix ("object.item.image") &&
- this.playback_state != "STOPPED") {
- this.setup_image_timeouts (item.lifetime);
- }
- }
- }
-
- private void reset () {
- this.playback_state = "STOPPED";
- this.track = 1;
- }
-
- private void setup_image_timeouts (long lifetime) {
- // For images, we handle the timeout here. Either the item carries a
- // dlna:lifetime tag, then we use that or we use a default timeout of
- // 5 minutes.
- var timeout = this.default_image_timeout;
- if (lifetime > 0) {
- timeout = (uint) lifetime;
- }
-
- debug ("Item is image, setup timer: %ld", timeout);
-
- if (this.timeout_id != 0) {
- Source.remove (this.timeout_id);
- }
-
- this.timeout_id = Timeout.add_seconds ((uint) timeout, () => {
- this.timeout_id = 0;
- if (!this.next ()) {
- this.reset ();
- }
-
- return false;
- });
- }
-
- private void on_setting_changed (string section, string key) {
- if (section != CONFIG_SECTION && key != TIMEOUT_KEY) {
- return;
- }
-
- try {
- this.default_image_timeout = config.get_int (CONFIG_SECTION,
- TIMEOUT_KEY,
- 0,
- int.MAX);
- } catch (Error error) {
- this.default_image_timeout = DEFAULT_IMAGE_TIMEOUT;
- }
-
- debug ("New image timeout: %lu", this.default_image_timeout);
- }
+ MediaCollection collection);
- private string unescape (string input) {
+ protected string unescape (string input) {
var result = input.replace (""", "\"");
result = result.replace ("<", "<");
result = result.replace (">", ">");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]