From f6c9fef31a6e11a2c54ee9529f85b97d98f02af7 Mon Sep 17 00:00:00 2001 From: nebojsa Date: Mon, 12 Oct 2009 02:40:09 +0000 Subject: [PATCH] added support for clipStart and clipEnd --- .../core/include/LiveSupport/Core/Playlist.h | 18 +++++++ .../LiveSupport/Core/PlaylistElement.h | 49 ++++++++++++++++++- .../include/LiveSupport/Core/XmlRpcTools.h | 24 +++++++++ campcaster/src/modules/core/src/Playlist.cxx | 44 +++++++++++++++++ .../src/modules/core/src/PlaylistElement.cxx | 32 ++++++++++++ .../src/modules/core/src/XmlRpcTools.cxx | 46 +++++++++++++++++ .../src/GstreamerPlayContext.h | 16 +++++- .../modules/storageServer/var/M3uPlaylist.php | 4 +- .../modules/storageServer/var/Playlist.php | 14 ++++-- .../storageServer/var/SmilPlaylist.php | 4 +- .../storageServer/var/playlistFormat.php | 2 +- .../var/xmlrpc/schedulerPhpClient.php | 4 +- .../gLiveSupport/src/GLiveSupport.cxx | 8 ++- .../products/gLiveSupport/src/GLiveSupport.h | 2 +- 14 files changed, 251 insertions(+), 16 deletions(-) diff --git a/campcaster/src/modules/core/include/LiveSupport/Core/Playlist.h b/campcaster/src/modules/core/include/LiveSupport/Core/Playlist.h index 1d11b6e6b..e11e11d4b 100644 --- a/campcaster/src/modules/core/include/LiveSupport/Core/Playlist.h +++ b/campcaster/src/modules/core/include/LiveSupport/Core/Playlist.h @@ -748,6 +748,24 @@ class Playlist : public Configurable, Ptr::Ref fadeInfo) throw (std::invalid_argument); + /** + * Set clipStart for a playlist element. + * + */ + void + setClipStart(Ptr::Ref playlistElementId, + Ptr::Ref newStart) + throw (std::invalid_argument); + + /** + * Set clipEnd for a playlist element. + * + */ + void + setClipEnd(Ptr::Ref playlistElementId, + Ptr::Ref newEnd) + throw (std::invalid_argument); + /** * Remove a playlist element from the playlist. * diff --git a/campcaster/src/modules/core/include/LiveSupport/Core/PlaylistElement.h b/campcaster/src/modules/core/include/LiveSupport/Core/PlaylistElement.h index 2967a41e3..f95fab834 100644 --- a/campcaster/src/modules/core/include/LiveSupport/Core/PlaylistElement.h +++ b/campcaster/src/modules/core/include/LiveSupport/Core/PlaylistElement.h @@ -130,6 +130,8 @@ class PlaylistElement : public Configurable * The starting time of the event. */ Ptr::Ref relativeOffset; + Ptr::Ref clipStart; + Ptr::Ref clipEnd; /** * The type of the entry (audio clip or sub-playlist). @@ -204,6 +206,9 @@ class PlaylistElement : public Configurable this->playable = audioClip; this->fadeInfo = fadeInfo; this->type = AudioClipType; + + setClipStart(Ptr::Ref(new time_duration(0,0,0,0))); + setClipEnd(Ptr::Ref(new time_duration(0,0,0,0))); } /** @@ -228,7 +233,10 @@ class PlaylistElement : public Configurable this->playable = audioClip; this->fadeInfo = fadeInfo; this->type = AudioClipType; - } + + setClipStart(Ptr::Ref(new time_duration(0,0,0,0))); + setClipEnd(Ptr::Ref(new time_duration(0,0,0,0))); + } /** * Create a new sub-playlist playlist element, with a new UniqueId, @@ -252,7 +260,10 @@ class PlaylistElement : public Configurable this->playable = playlist; this->fadeInfo = fadeInfo; this->type = PlaylistType; - } + + setClipStart(Ptr::Ref(new time_duration(0,0,0,0))); + setClipEnd(Ptr::Ref(new time_duration(0,0,0,0))); + } /** * A virtual destructor, as this class has virtual functions. @@ -324,6 +335,40 @@ class PlaylistElement : public Configurable return relativeOffset; } + /** + */ + void + setClipStart(Ptr::Ref newStart) + throw () + { + clipStart = newStart; + } + + /** + */ + Ptr::Ref + getClipStart(void) const throw () + { + return clipStart; + } + + /** + */ + void + setClipEnd(Ptr::Ref newEnd) + throw () + { + clipEnd = newEnd; + } + + /** + */ + Ptr::Ref + getClipEnd(void) const throw () + { + return clipEnd; + } + /** * Return the type of this playlist element. If the return * value is PlaylistElement::AudioClipType (resp. PlaylistType), diff --git a/campcaster/src/modules/core/include/LiveSupport/Core/XmlRpcTools.h b/campcaster/src/modules/core/include/LiveSupport/Core/XmlRpcTools.h index 193afb086..83364c27a 100644 --- a/campcaster/src/modules/core/include/LiveSupport/Core/XmlRpcTools.h +++ b/campcaster/src/modules/core/include/LiveSupport/Core/XmlRpcTools.h @@ -180,6 +180,30 @@ class XmlRpcTools extractRelativeOffset(XmlRpc::XmlRpcValue & xmlRpcValue) throw (std::invalid_argument); + /** + * Extract the relative offset from the XML-RPC parameters. + * + * @param xmlRpcValue the XML-RPC parameter to extract from. + * @return a time_duration that was found in the XML-RPC parameter. + * @exception std::invalid_argument if there was no relativeOffset + * member in xmlRpcValue + */ + static Ptr::Ref + extractClipStart(XmlRpc::XmlRpcValue & xmlRpcValue) + throw (std::invalid_argument); + + /** + * Extract the relative offset from the XML-RPC parameters. + * + * @param xmlRpcValue the XML-RPC parameter to extract from. + * @return a time_duration that was found in the XML-RPC parameter. + * @exception std::invalid_argument if there was no relativeOffset + * member in xmlRpcValue + */ + static Ptr::Ref + extractClipEnd(XmlRpc::XmlRpcValue & xmlRpcValue) + throw (std::invalid_argument); + /** * Convert a Playlist to an XmlRpcValue * diff --git a/campcaster/src/modules/core/src/Playlist.cxx b/campcaster/src/modules/core/src/Playlist.cxx index 7b877a985..a79d14cc7 100644 --- a/campcaster/src/modules/core/src/Playlist.cxx +++ b/campcaster/src/modules/core/src/Playlist.cxx @@ -545,6 +545,50 @@ Playlist::setFadeInfo(Ptr::Ref playlistElementId, it->second->setFadeInfo(fadeInfo); } +/*------------------------------------------------------------------------------ + * Change clipStart of a playlist element. + *----------------------------------------------------------------------------*/ +void +Playlist::setClipStart(Ptr::Ref playlistElementId, + Ptr::Ref newStart) + throw (std::invalid_argument) +{ + Playlist::iterator it = this->find(playlistElementId); + + if (it == this->end()) { + throw std::invalid_argument("no playlist element with this ID"); + } + + Ptr::Ref endOffset(new time_duration( + *it->second->getRelativeOffset() + + *it->second->getPlayable()->getPlaylength() - *newStart)); + setPlaylength(endOffset); + + it->second->setClipStart(newStart); +} + +/*------------------------------------------------------------------------------ + * Change clipEnd of a playlist element. + *----------------------------------------------------------------------------*/ +void +Playlist::setClipEnd(Ptr::Ref playlistElementId, + Ptr::Ref newEnd) + throw (std::invalid_argument) +{ + Playlist::iterator it = this->find(playlistElementId); + + if (it == this->end()) { + throw std::invalid_argument("no playlist element with this ID"); + } + + Ptr::Ref endOffset(new time_duration( + *it->second->getRelativeOffset() + + *newEnd - *it->second->getClipStart())); + setPlaylength(endOffset); + + it->second->setClipEnd(newEnd); +} + /*------------------------------------------------------------------------------ * Remove a playlist element from the playlist. diff --git a/campcaster/src/modules/core/src/PlaylistElement.cxx b/campcaster/src/modules/core/src/PlaylistElement.cxx index d15aa3b98..9be361708 100644 --- a/campcaster/src/modules/core/src/PlaylistElement.cxx +++ b/campcaster/src/modules/core/src/PlaylistElement.cxx @@ -63,6 +63,14 @@ static const std::string idAttrName = "id"; */ static const std::string relativeOffsetAttrName = "relativeOffset"; +/** + */ +static const std::string clipStartAttrName = "clipStart"; + +/** + */ +static const std::string clipEndAttrName = "clipEnd"; + /** * The name of the audio clip child element of the playlist element. */ @@ -117,6 +125,24 @@ PlaylistElement :: configure(const xmlpp::Element & element) attribute->get_value() )); relativeOffset = TimeConversion::parseTimeDuration(relativeOffsetString); + // set clip start + if (attribute = element.get_attribute(clipStartAttrName)) { + Ptr::Ref clipStartString(new std::string( + attribute->get_value() )); + clipStart = TimeConversion::parseTimeDuration(clipStartString); + } else { + setClipStart(Ptr::Ref(new time_duration(0,0,0,0))); + } + + // set clip end + if (attribute = element.get_attribute(clipEndAttrName)) { + Ptr::Ref clipEndString(new std::string( + attribute->get_value() )); + clipEnd = TimeConversion::parseTimeDuration(clipEndString); + } else { + setClipEnd(Ptr::Ref(new time_duration(0,0,0,0))); + } + // set audio clip xmlpp::Node::NodeList childNodes = element.get_children(audioClipElementName); @@ -202,6 +228,12 @@ PlaylistElement :: getXmlElementString(void) throw () + "\" "); xmlString->append(relativeOffsetAttrName + "=\"" + toFixedString(relativeOffset) + + "\" "); + xmlString->append(clipStartAttrName + "=\"" + + toFixedString(clipStart) + + "\" "); + xmlString->append(clipEndAttrName + "=\"" + + toFixedString(clipEnd) + "\">\n"); xmlString->append(*getPlayable()->getXmlElementString() + "\n"); diff --git a/campcaster/src/modules/core/src/XmlRpcTools.cxx b/campcaster/src/modules/core/src/XmlRpcTools.cxx index 68cc24fc4..47bff8b59 100644 --- a/campcaster/src/modules/core/src/XmlRpcTools.cxx +++ b/campcaster/src/modules/core/src/XmlRpcTools.cxx @@ -81,6 +81,16 @@ const std::string playlistElementIdName = "playlistElementId"; *----------------------------------------------------------------------------*/ const std::string relativeOffsetName = "relativeOffset"; +/*------------------------------------------------------------------------------ + * The name of the relative offset member in the XML-RPC parameter structure + *----------------------------------------------------------------------------*/ +const std::string clipStartName = "clipStart"; + +/*------------------------------------------------------------------------------ + * The name of the relative offset member in the XML-RPC parameter structure + *----------------------------------------------------------------------------*/ +const std::string clipEndName = "clipEnd"; + /*------------------------------------------------------------------------------ * The name of the from member in the XML-RPC parameter structure. *----------------------------------------------------------------------------*/ @@ -272,6 +282,42 @@ XmlRpcTools :: extractAudioClipId(XmlRpc::XmlRpcValue & xmlRpcValue) return id; } +/*------------------------------------------------------------------------------ + * Extract the relative offset from an XML-RPC function call parameter + *----------------------------------------------------------------------------*/ +Ptr::Ref +XmlRpcTools :: extractClipStart(XmlRpc::XmlRpcValue & xmlRpcValue) + throw (std::invalid_argument) +{ + if (!xmlRpcValue.hasMember(clipStartName) + || xmlRpcValue[clipStartName].getType() + != XmlRpc::XmlRpcValue::TypeInt) { + throw std::invalid_argument("missing clip start argument"); + } + + Ptr::Ref clipStart(new time_duration(0,0, + int(xmlRpcValue[clipStartName]), 0)); + return clipStart; +} + +/*------------------------------------------------------------------------------ + * Extract the relative offset from an XML-RPC function call parameter + *----------------------------------------------------------------------------*/ +Ptr::Ref +XmlRpcTools :: extractClipEnd(XmlRpc::XmlRpcValue & xmlRpcValue) + throw (std::invalid_argument) +{ + if (!xmlRpcValue.hasMember(clipEndName) + || xmlRpcValue[clipEndName].getType() + != XmlRpc::XmlRpcValue::TypeInt) { + throw std::invalid_argument("missing clip end argument"); + } + + Ptr::Ref clipEnd(new time_duration(0,0, + int(xmlRpcValue[clipEndName]), 0)); + return clipEnd; +} + /*------------------------------------------------------------------------------ * Extract the relative offset from an XML-RPC function call parameter diff --git a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h index 43df1b844..bac18692d 100644 --- a/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h +++ b/campcaster/src/modules/playlistExecutor/src/GstreamerPlayContext.h @@ -134,7 +134,19 @@ public: } void playContext(){ - gst_element_set_state (m_pipeline, GST_STATE_PLAYING); + GstStateChangeReturn st = gst_element_set_state (m_pipeline, GST_STATE_PLAYING); + if(NULL != m_audioDescription) + { + //enforce PLAYING state in case this was an asynch state change + //this is essential for seek to succeed + if(GST_STATE_CHANGE_ASYNC == st) + { + GstState state, pending; + gst_element_get_state (m_pipeline, &state, &pending, 2000000000);//just in case, do not wait for more than 2 sec + } + gst_element_seek(m_pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, + m_audioDescription->m_clipBegin*GST_NSECOND, GST_SEEK_TYPE_SET, m_audioDescription->m_clipEnd*GST_NSECOND); + } g_object_set(G_OBJECT(m_volume), "volume", 1.0, NULL); } @@ -359,7 +371,7 @@ private: * Prepare animations bin. *----------------------------------------------------------------------------*/ bool prepareAnimations(){ - if(m_audioDescription && m_audioDescription->m_animations.size() > 0){ + if(m_audioDescription && m_audioDescription->m_animations.size() > 0){ m_ctrl = gst_controller_new (G_OBJECT (m_volume), "volume", NULL); if (m_ctrl == NULL) { return false; diff --git a/campcaster/src/modules/storageServer/var/M3uPlaylist.php b/campcaster/src/modules/storageServer/var/M3uPlaylist.php index e56b2b073..c07cb6865 100644 --- a/campcaster/src/modules/storageServer/var/M3uPlaylist.php +++ b/campcaster/src/modules/storageServer/var/M3uPlaylist.php @@ -166,6 +166,8 @@ class M3uPlaylist { $gunid2 = StoredFile::CreateGunid(); $length = Playlist::secondsToPlaylistTime($length); $offset = '???'; + $clipStart = '???'; + $clipEnd = '???'; $uri_h = preg_replace("|--|", "d;d;", htmlspecialchars("$uri")); if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) { switch (strtolower($ext = $va[1])) { @@ -184,7 +186,7 @@ class M3uPlaylist { break; } } - $res .= "$ind2\n". + $res .= "$ind2\n". $acOrPl. "$ind2\n"; } diff --git a/campcaster/src/modules/storageServer/var/Playlist.php b/campcaster/src/modules/storageServer/var/Playlist.php index 16ec7680c..16ccc786f 100644 --- a/campcaster/src/modules/storageServer/var/Playlist.php +++ b/campcaster/src/modules/storageServer/var/Playlist.php @@ -414,6 +414,16 @@ class Playlist extends StoredFile { if (PEAR::isError($offArr)) { return $offArr; } + // get clipStart: + $startArr = $this->md->getMetadataElement('clipStart', $elId); + if (PEAR::isError($startArr)) { + return $startArr; + } + // get clipEnd: + $endArr = $this->md->getMetadataElement('clipEnd', $elId); + if (PEAR::isError($endArr)) { + return $endArr; + } $offsetId = $offArr[0]['mid']; $offset = $offArr[0]['value']; // get audioClip: @@ -460,10 +470,6 @@ class Playlist extends StoredFile { "Playlist::recalculateTimes: fadeIn too big"); } } - // $peArr[] = array('id'=>$elId, 'gunid'=>$plElGunid, 'len'=>$acLen, - // 'offset'=>$offset, 'offsetId'=>$offsetId, - // 'fadeIn'=>$fadeIn, 'fadeOut'=>$fadeOut); - // set relativeOffset: if ($len > 0) { $len = $len - $fadeInS; } diff --git a/campcaster/src/modules/storageServer/var/SmilPlaylist.php b/campcaster/src/modules/storageServer/var/SmilPlaylist.php index 0097bdae1..3a6fdf790 100644 --- a/campcaster/src/modules/storageServer/var/SmilPlaylist.php +++ b/campcaster/src/modules/storageServer/var/SmilPlaylist.php @@ -276,7 +276,9 @@ class SmilPlaylistAudioElement { $title = basename($tree->attrs['src']->val); $offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val); - $res = "$ind\n". + $clipStart = Playlist::secondsToPlaylistTime($tree->attrs['clipStart']->val); + $clipEnd = Playlist::secondsToPlaylistTime($tree->attrs['clipEnd']->val); + $res = "$ind\n". "$ind2<$type id=\"$acGunid\" playlength=\"$playlength\" title=\"$title\"/>\n". $fInfo. "$ind\n"; diff --git a/campcaster/src/modules/storageServer/var/playlistFormat.php b/campcaster/src/modules/storageServer/var/playlistFormat.php index ca4fe00f7..7f4895a91 100644 --- a/campcaster/src/modules/storageServer/var/playlistFormat.php +++ b/campcaster/src/modules/storageServer/var/playlistFormat.php @@ -29,7 +29,7 @@ $playlistFormat = array( 'optional'=>array('fadeInfo'), ), 'attrs'=>array( - 'required'=>array('id', 'relativeOffset'), + 'required'=>array('id', 'relativeOffset', 'clipStart', 'clipEnd'), ), ), 'audioClip'=>array( diff --git a/campcaster/src/modules/storageServer/var/xmlrpc/schedulerPhpClient.php b/campcaster/src/modules/storageServer/var/xmlrpc/schedulerPhpClient.php index 867159a12..fa5f47980 100644 --- a/campcaster/src/modules/storageServer/var/xmlrpc/schedulerPhpClient.php +++ b/campcaster/src/modules/storageServer/var/xmlrpc/schedulerPhpClient.php @@ -26,8 +26,8 @@ $mdefs = array( "listMethods" => array('m'=>"system.listMethods", 'p'=>NULL, 't'=>NULL), "AddAudioClipToPlaylistMethod" => array( 'm'=>'addAudioClipToPlaylist', - 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'audioClipId'/*string*/, 'relativeOffset'/*int*/), - 't'=>array('string', 'string', 'string', 'int'), + 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'audioClipId'/*string*/, 'relativeOffset'/*int*/, 'clipStart'/*int*/, 'clipEnd'/*int*/), + 't'=>array('string', 'string', 'string', 'int', 'int', 'int'), 'r'=>array('playlistElementId'/*string*/), 'e'=>array( '301'=>'invalid argument format', diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx index 40e8ae5aa..08e5f349a 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx @@ -1175,7 +1175,7 @@ GLiveSupport :: cancelEditedPlaylist(void) *----------------------------------------------------------------------------*/ void LiveSupport :: GLiveSupport :: -GLiveSupport :: addToPlaylist(Ptr::Ref id) +GLiveSupport :: addToPlaylist(Ptr::Ref id) throw (XmlRpcException) { if (!editedPlaylist.get()) { @@ -1188,7 +1188,11 @@ GLiveSupport :: addToPlaylist(Ptr::Ref id) editedPlaylist->addPlaylist(playlist, editedPlaylist->getPlaylength()); } else if (existsAudioClip(id)) { Ptr::Ref clip = getAudioClip(id); - editedPlaylist->addAudioClip(clip, editedPlaylist->getPlaylength()); + Ptr::Ref elid = editedPlaylist->addAudioClip(clip, editedPlaylist->getPlaylength()); + + //TODO: for testing only!!!!!!!!! +// editedPlaylist->setClipStart(elid, Ptr::Ref(new time_duration(seconds(5)))); +// editedPlaylist->setClipEnd(elid, Ptr::Ref(new time_duration(seconds(10)))); } masterPanel->updatePlaylistWindow(); diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h index f5171cb74..cd35305d9 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h @@ -906,7 +906,7 @@ class GLiveSupport : public LocalizedConfigurable, * @see #releaseEditedPlaylist */ void - addToPlaylist(Ptr::Ref id) + addToPlaylist(Ptr::Ref id) throw (XmlRpcException); /** * Save the currently edited playlist in storage.