added support for playlist element length

This commit is contained in:
nebojsa 2009-11-05 23:13:06 +00:00
parent 1f05438448
commit 9b88996d92
18 changed files with 231 additions and 61 deletions

View file

@ -132,6 +132,7 @@ class PlaylistElement : public Configurable
Ptr<time_duration>::Ref relativeOffset; Ptr<time_duration>::Ref relativeOffset;
Ptr<time_duration>::Ref clipStart; Ptr<time_duration>::Ref clipStart;
Ptr<time_duration>::Ref clipEnd; Ptr<time_duration>::Ref clipEnd;
Ptr<time_duration>::Ref clipLength;
/** /**
* The type of the entry (audio clip or sub-playlist). * The type of the entry (audio clip or sub-playlist).
@ -195,6 +196,7 @@ class PlaylistElement : public Configurable
*/ */
PlaylistElement(Ptr<UniqueId>::Ref id, PlaylistElement(Ptr<UniqueId>::Ref id,
Ptr<time_duration>::Ref relativeOffset, Ptr<time_duration>::Ref relativeOffset,
Ptr<time_duration>::Ref clipLength,
Ptr<AudioClip>::Ref audioClip, Ptr<AudioClip>::Ref audioClip,
Ptr<FadeInfo>::Ref fadeInfo Ptr<FadeInfo>::Ref fadeInfo
= Ptr<FadeInfo>::Ref()) = Ptr<FadeInfo>::Ref())
@ -202,6 +204,7 @@ class PlaylistElement : public Configurable
{ {
this->id = id; this->id = id;
this->relativeOffset = relativeOffset; this->relativeOffset = relativeOffset;
this->clipLength = clipLength;
this->audioClip = audioClip; this->audioClip = audioClip;
this->playable = audioClip; this->playable = audioClip;
this->fadeInfo = fadeInfo; this->fadeInfo = fadeInfo;
@ -222,6 +225,7 @@ class PlaylistElement : public Configurable
* @param fadeInfo fade in / fade out information (optional) * @param fadeInfo fade in / fade out information (optional)
*/ */
PlaylistElement(Ptr<time_duration>::Ref relativeOffset, PlaylistElement(Ptr<time_duration>::Ref relativeOffset,
Ptr<time_duration>::Ref clipLength,
Ptr<AudioClip>::Ref audioClip, Ptr<AudioClip>::Ref audioClip,
Ptr<FadeInfo>::Ref fadeInfo Ptr<FadeInfo>::Ref fadeInfo
= Ptr<FadeInfo>::Ref()) = Ptr<FadeInfo>::Ref())
@ -229,6 +233,7 @@ class PlaylistElement : public Configurable
{ {
this->id = UniqueId::generateId(); this->id = UniqueId::generateId();
this->relativeOffset = relativeOffset; this->relativeOffset = relativeOffset;
this->clipLength = clipLength;
this->audioClip = audioClip; this->audioClip = audioClip;
this->playable = audioClip; this->playable = audioClip;
this->fadeInfo = fadeInfo; this->fadeInfo = fadeInfo;
@ -249,6 +254,7 @@ class PlaylistElement : public Configurable
* @param fadeInfo fade in / fade out information (optional) * @param fadeInfo fade in / fade out information (optional)
*/ */
PlaylistElement(Ptr<time_duration>::Ref relativeOffset, PlaylistElement(Ptr<time_duration>::Ref relativeOffset,
Ptr<time_duration>::Ref clipLength,
Ptr<Playlist>::Ref playlist, Ptr<Playlist>::Ref playlist,
Ptr<FadeInfo>::Ref fadeInfo Ptr<FadeInfo>::Ref fadeInfo
= Ptr<FadeInfo>::Ref()) = Ptr<FadeInfo>::Ref())
@ -256,6 +262,7 @@ class PlaylistElement : public Configurable
{ {
this->id = UniqueId::generateId(); this->id = UniqueId::generateId();
this->relativeOffset = relativeOffset; this->relativeOffset = relativeOffset;
this->clipLength = clipLength;
this->playlist = playlist; this->playlist = playlist;
this->playable = playlist; this->playable = playlist;
this->fadeInfo = fadeInfo; this->fadeInfo = fadeInfo;
@ -369,6 +376,23 @@ class PlaylistElement : public Configurable
return clipEnd; return clipEnd;
} }
/**
*/
void
setClipLength(Ptr<time_duration>::Ref newLength)
throw ()
{
clipLength = newLength;
}
/**
*/
Ptr<time_duration>::Ref
getClipLength(void) const throw ()
{
return clipLength;
}
/** /**
* Return the type of this playlist element. If the return * Return the type of this playlist element. If the return
* value is PlaylistElement::AudioClipType (resp. PlaylistType), * value is PlaylistElement::AudioClipType (resp. PlaylistType),

View file

@ -204,6 +204,18 @@ class XmlRpcTools
extractClipEnd(XmlRpc::XmlRpcValue & xmlRpcValue) extractClipEnd(XmlRpc::XmlRpcValue & xmlRpcValue)
throw (std::invalid_argument); 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<time_duration>::Ref
extractClipLength(XmlRpc::XmlRpcValue & xmlRpcValue)
throw (std::invalid_argument);
/** /**
* Convert a Playlist to an XmlRpcValue * Convert a Playlist to an XmlRpcValue
* *

View file

@ -474,7 +474,7 @@ Playlist::addAudioClip(Ptr<AudioClip>::Ref audioClip,
throw () throw ()
{ {
Ptr<PlaylistElement>::Ref playlistElement(new PlaylistElement( Ptr<PlaylistElement>::Ref playlistElement(new PlaylistElement(
relativeOffset, audioClip, fadeInfo)); relativeOffset, audioClip->getPlaylength(), audioClip, fadeInfo));
elementList->insert(std::make_pair(*relativeOffset, playlistElement)); elementList->insert(std::make_pair(*relativeOffset, playlistElement));
Ptr<time_duration>::Ref endOffset(new time_duration( Ptr<time_duration>::Ref endOffset(new time_duration(
@ -498,7 +498,7 @@ Playlist::addPlaylist(Ptr<Playlist>::Ref playlist,
throw () throw ()
{ {
Ptr<PlaylistElement>::Ref playlistElement(new PlaylistElement( Ptr<PlaylistElement>::Ref playlistElement(new PlaylistElement(
relativeOffset, playlist, fadeInfo)); relativeOffset, playlist->getPlaylength(), playlist, fadeInfo));
elementList->insert(std::make_pair(*relativeOffset, playlistElement)); elementList->insert(std::make_pair(*relativeOffset, playlistElement));
Ptr<time_duration>::Ref endOffset(new time_duration( Ptr<time_duration>::Ref endOffset(new time_duration(

View file

@ -71,6 +71,10 @@ static const std::string clipStartAttrName = "clipStart";
*/ */
static const std::string clipEndAttrName = "clipEnd"; static const std::string clipEndAttrName = "clipEnd";
/**
*/
static const std::string clipLengthAttrName = "clipLength";
/** /**
* The name of the audio clip child element of the playlist element. * The name of the audio clip child element of the playlist element.
*/ */
@ -143,6 +147,15 @@ PlaylistElement :: configure(const xmlpp::Element & element)
setClipEnd(Ptr<time_duration>::Ref(new time_duration(0,0,0,0))); setClipEnd(Ptr<time_duration>::Ref(new time_duration(0,0,0,0)));
} }
// set clip length
if (attribute = element.get_attribute(clipLengthAttrName)) {
Ptr<std::string>::Ref clipLengthString(new std::string(
attribute->get_value() ));
clipLength = TimeConversion::parseTimeDuration(clipLengthString);
} else {
setClipLength(Ptr<time_duration>::Ref(new time_duration(0,0,0,0)));
}
// set audio clip // set audio clip
xmlpp::Node::NodeList childNodes xmlpp::Node::NodeList childNodes
= element.get_children(audioClipElementName); = element.get_children(audioClipElementName);
@ -235,6 +248,9 @@ PlaylistElement :: getXmlElementString(void) throw ()
xmlString->append(clipEndAttrName + "=\"" xmlString->append(clipEndAttrName + "=\""
+ toFixedString(clipEnd) + toFixedString(clipEnd)
+ "\">\n"); + "\">\n");
xmlString->append(clipLengthAttrName + "=\""
+ toFixedString(clipLength)
+ "\">\n");
xmlString->append(*getPlayable()->getXmlElementString() + "\n"); xmlString->append(*getPlayable()->getXmlElementString() + "\n");
if (fadeInfo) { if (fadeInfo) {

View file

@ -91,6 +91,11 @@ const std::string clipStartName = "clipStart";
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
const std::string clipEndName = "clipEnd"; const std::string clipEndName = "clipEnd";
/*------------------------------------------------------------------------------
* The name of the relative offset member in the XML-RPC parameter structure
*----------------------------------------------------------------------------*/
const std::string clipLengthName = "clipLength";
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* The name of the from member in the XML-RPC parameter structure. * The name of the from member in the XML-RPC parameter structure.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
@ -318,6 +323,23 @@ XmlRpcTools :: extractClipEnd(XmlRpc::XmlRpcValue & xmlRpcValue)
return clipEnd; return clipEnd;
} }
/*------------------------------------------------------------------------------
* Extract the relative offset from an XML-RPC function call parameter
*----------------------------------------------------------------------------*/
Ptr<time_duration>::Ref
XmlRpcTools :: extractClipLength(XmlRpc::XmlRpcValue & xmlRpcValue)
throw (std::invalid_argument)
{
if (!xmlRpcValue.hasMember(clipLengthName)
|| xmlRpcValue[clipLengthName].getType()
!= XmlRpc::XmlRpcValue::TypeInt) {
throw std::invalid_argument("missing clip length argument");
}
Ptr<time_duration>::Ref clipLength(new time_duration(0,0,
int(xmlRpcValue[clipLengthName]), 0));
return clipLength;
}
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Extract the relative offset from an XML-RPC function call parameter * Extract the relative offset from an XML-RPC function call parameter

View file

@ -153,7 +153,7 @@ class AudioPlayerInterface
* @see #start * @see #start
*/ */
virtual bool virtual bool
open(const std::string fileUrl, gint64 id) open(const std::string fileUrl, gint64 id, gint64 offset)
throw (std::invalid_argument, std::runtime_error) = 0; throw (std::invalid_argument, std::runtime_error) = 0;
/** /**
@ -204,7 +204,7 @@ class AudioPlayerInterface
* @see #stop * @see #stop
*/ */
virtual void virtual void
start(gint64) throw (std::logic_error) start() throw (std::logic_error)
= 0; = 0;
/** /**

View file

@ -156,11 +156,11 @@ AudioPlayerFactoryGstreamerTest :: simplePlayTest(void)
audioPlayer = audioPlayerFactory->getAudioPlayer(); audioPlayer = audioPlayerFactory->getAudioPlayer();
// CPPUNIT_ASSERT_NO_THROW( // CPPUNIT_ASSERT_NO_THROW(
audioPlayer->open("file:///tmp/campcaster/simple.smil", 0); audioPlayer->open("file:///tmp/campcaster/simple.smil", 0L, 0L);
// ); // );
// CPPUNIT_ASSERT(!audioPlayer->isPlaying()); // CPPUNIT_ASSERT(!audioPlayer->isPlaying());
// CPPUNIT_ASSERT_NO_THROW( // CPPUNIT_ASSERT_NO_THROW(
audioPlayer->start(0, -1); audioPlayer->start();
g_main_loop_run(loop); g_main_loop_run(loop);

View file

@ -253,7 +253,7 @@ GstreamerPlayer :: preload(const std::string fileUrl)
* Specify which file to play * Specify which file to play
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
bool bool
GstreamerPlayer :: open(const std::string fileUri, gint64 id) GstreamerPlayer :: open(const std::string fileUri, gint64 id, gint64 offset)
throw (std::invalid_argument, std::runtime_error) throw (std::invalid_argument, std::runtime_error)
{ {
DEBUG_BLOCK DEBUG_BLOCK
@ -273,8 +273,10 @@ GstreamerPlayer :: open(const std::string fileUri, gint64 id)
m_playContext->setAudioDevice(m_audioDevice); m_playContext->setAudioDevice(m_audioDevice);
if (fileUri.find(std::string(".smil")) != std::string::npos) { if (fileUri.find(std::string(".smil")) != std::string::npos) {
m_smilHandler = new SmilHandler(); m_smilHandler = new SmilHandler();
m_smilHandler->openSmilFile(fileUri.c_str()); m_smilHandler->openSmilFile(fileUri.c_str(), offset);
AudioDescription *audioDescription = m_smilHandler->getNext(); AudioDescription *audioDescription = m_smilHandler->getNext();
gint64 clipOffset = m_smilHandler->getClipOffset();
m_playContext->setClipOffset(clipOffset);
m_Id = audioDescription->m_Id; m_Id = audioDescription->m_Id;
m_open=m_playContext->openSource(audioDescription); m_open=m_playContext->openSource(audioDescription);
m_url = (const char*) audioDescription->m_src; m_url = (const char*) audioDescription->m_src;
@ -383,19 +385,11 @@ GstreamerPlayer :: getPosition(void) throw (std::logic_error)
return length; return length;
} }
gint64
GstreamerPlayer :: offsetSmil(gint64 startTime)
{
//have to take start_time, offset the smilHandler based on it (remove all clips that fall before start_time)
//and calculate clip offset as a reminder, then set that offset to the player somehow
return 0;
}
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Start playing * Start playing
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void void
GstreamerPlayer :: start(gint64 startTime) throw (std::logic_error) GstreamerPlayer :: start() throw (std::logic_error)
{ {
DEBUG_BLOCK DEBUG_BLOCK
if (!isOpen()) { if (!isOpen()) {
@ -403,8 +397,6 @@ GstreamerPlayer :: start(gint64 startTime) throw (std::logi
} }
if (!isPlaying()) { if (!isPlaying()) {
gint64 clipOffset = offsetSmil(startTime);
m_playContext->setClipOffset(clipOffset);
m_playContext->playContext(); m_playContext->playContext();
}else{ }else{
error() << "Already playing!" << endl; error() << "Already playing!" << endl;

View file

@ -127,7 +127,6 @@ class GstreamerPlayer : virtual public Configurable,
gint64 m_currentPlayLength; gint64 m_currentPlayLength;
gint64 m_Id; gint64 m_Id;
gint64 offsetSmil(gint64);//private helper to handle playback offset
public: public:
/** /**
* Contains runtime error messages from GStreamer. * Contains runtime error messages from GStreamer.
@ -287,7 +286,7 @@ public:
* @see #start * @see #start
*/ */
virtual bool virtual bool
open(const std::string fileUrl, gint64 id) open(const std::string fileUrl, gint64 id, gint64 offset)
throw (std::invalid_argument, std::runtime_error); throw (std::invalid_argument, std::runtime_error);
/** /**
@ -328,7 +327,7 @@ public:
* @see #stop * @see #stop
*/ */
virtual void virtual void
start(gint64) throw (std::logic_error); start() throw (std::logic_error);
/** /**
* Pause the player. * Pause the player.

View file

@ -99,6 +99,7 @@ public:
gint64 m_begin; gint64 m_begin;
gint64 m_clipBegin; gint64 m_clipBegin;
gint64 m_clipEnd; gint64 m_clipEnd;
gint64 m_clipLength;
gint64 m_Id; gint64 m_Id;
std::vector<AnimationDescription*> m_animations; std::vector<AnimationDescription*> m_animations;
@ -107,6 +108,7 @@ public:
m_begin(0), m_begin(0),
m_clipBegin(0), m_clipBegin(0),
m_clipEnd(0), m_clipEnd(0),
m_clipLength(0),
m_Id(0) m_Id(0)
{ {
} }
@ -147,6 +149,7 @@ class SmilHandler
xmlNode *m_bodyChildren; xmlNode *m_bodyChildren;
xmlNode *m_parChildren; xmlNode *m_parChildren;
SmilHandler *m_subSmil; SmilHandler *m_subSmil;
gint64 m_smilOffset;
public: public:
@ -155,6 +158,7 @@ public:
m_bodyChildren = NULL; m_bodyChildren = NULL;
m_parChildren = NULL; m_parChildren = NULL;
m_subSmil = NULL; m_subSmil = NULL;
m_smilOffset = 0L;
} }
~SmilHandler(){ ~SmilHandler(){
@ -172,8 +176,9 @@ public:
* @para smil a MinimalAudioSmil object. * @para smil a MinimalAudioSmil object.
* @return TRUE if processing was successful, FALSE otherwise. * @return TRUE if processing was successful, FALSE otherwise.
*/ */
gboolean openSmilFile(const gchar *xmlFile){ gboolean openSmilFile(const gchar *xmlFile, gint64 offset){
xmlNode *node; xmlNode *node;
m_smilOffset = offset;
/* parse the XML files */ /* parse the XML files */
m_document = xmlReadFile(xmlFile, NULL, XML_PARSE_RECOVER); m_document = xmlReadFile(xmlFile, NULL, XML_PARSE_RECOVER);
@ -193,8 +198,88 @@ public:
emptysmilrecovery: emptysmilrecovery:
AudioDescription *audioDescription = NULL; AudioDescription *audioDescription = NULL;
//TODO: m_smilOffset must contain correct clipOffset once this function exits!!!!!!
if(m_subSmil != NULL){ if(m_subSmil != NULL){
audioDescription = m_subSmil->getNext(); audioDescription = m_subSmil->getNextInternal();
if(audioDescription == NULL){
delete m_subSmil;
m_subSmil = NULL;
}else{
if(m_smilOffset >= audioDescription->m_clipLength)
{
m_smilOffset -= audioDescription->m_clipLength;
goto emptysmilrecovery;
}
return audioDescription;
}
}
if(m_parChildren){//we are currently traversing par segment
audioDescription = getNextPar();
}
if(audioDescription == NULL && m_bodyChildren){//par exaused, see if there is more in the body segment
for (; m_bodyChildren; m_bodyChildren = m_bodyChildren->next) {
if (m_bodyChildren->type == XML_ELEMENT_NODE) {
if (!strcmp((const char*)m_bodyChildren->name, "par")) {
m_parChildren = m_bodyChildren->children;
audioDescription = getNextPar();
if(audioDescription != NULL){
m_bodyChildren = m_bodyChildren->next;
break;
}
} else {
GST_WARNING("unsupported SMIL element %s found", m_bodyChildren->name);
}
}
}
}
if(audioDescription != NULL && std::string(audioDescription->m_src).find(".smil") != std::string::npos){//we have a sub smil
m_subSmil = new SmilHandler();
m_subSmil->openSmilFile(audioDescription->m_src, m_smilOffset);
delete audioDescription;
audioDescription = m_subSmil->getNextInternal();
if(audioDescription == NULL){
delete m_subSmil;
m_subSmil = NULL;
goto emptysmilrecovery;
}
}
if(audioDescription != NULL && m_smilOffset >= audioDescription->m_clipLength)
{
m_smilOffset -= audioDescription->m_clipLength;
goto emptysmilrecovery;
}
return audioDescription;
}
gint64 getClipOffset() {
gint64 offset = m_smilOffset;
m_smilOffset = 0L;//offset only valid after the first getNext
return offset;
}
gint64 getPlayLength() throw() {
gint64 ns = 0LL;
//TODO: calculate proper playlist length
return ns;
}
private:
/**
* Fetch next audio entry in sequence.
* @return AudioDescription object if processing was successful, NULL otherwise.
*/
AudioDescription *getNextInternal(){
emptysmilrecoveryint:
AudioDescription *audioDescription = NULL;
if(m_subSmil != NULL){
audioDescription = m_subSmil->getNextInternal();
if(audioDescription == NULL){ if(audioDescription == NULL){
delete m_subSmil; delete m_subSmil;
m_subSmil = NULL; m_subSmil = NULL;
@ -226,27 +311,19 @@ emptysmilrecovery:
if(audioDescription != NULL && std::string(audioDescription->m_src).find(".smil") != std::string::npos){//we have a sub smil if(audioDescription != NULL && std::string(audioDescription->m_src).find(".smil") != std::string::npos){//we have a sub smil
m_subSmil = new SmilHandler(); m_subSmil = new SmilHandler();
m_subSmil->openSmilFile(audioDescription->m_src); m_subSmil->openSmilFile(audioDescription->m_src, m_smilOffset);
delete audioDescription; delete audioDescription;
audioDescription = m_subSmil->getNext(); audioDescription = m_subSmil->getNextInternal();
if(audioDescription == NULL){ if(audioDescription == NULL){
delete m_subSmil; delete m_subSmil;
m_subSmil = NULL; m_subSmil = NULL;
goto emptysmilrecovery; goto emptysmilrecoveryint;
} }
} }
return audioDescription; return audioDescription;
} }
gint64 getPlayLength() throw() {
gint64 ns = 0LL;
//TODO: calculate proper playlist length
return ns;
}
private:
/** /**
* Fetch next audio entry from "<par>" SMIL segment. * Fetch next audio entry from "<par>" SMIL segment.
* *
@ -281,11 +358,12 @@ private:
xmlNode * node; xmlNode * node;
xmlAttribute * attr; xmlAttribute * attr;
gchar * src = 0; gchar * src = 0;
gchar * begin = 0; gchar * begin = 0;
gchar * clipBegin = 0; gchar * clipBegin = 0;
gchar * clipEnd = 0; gchar * clipEnd = 0;
gchar * idStr = 0; gchar * clipLength = 0;
gchar * idStr = 0;
/* handle the attributes */ /* handle the attributes */
for (attr = ((xmlElement*)audio)->attributes; attr; attr = (xmlAttribute*) attr->next) { for (attr = ((xmlElement*)audio)->attributes; attr; attr = (xmlAttribute*) attr->next) {
@ -311,6 +389,10 @@ private:
if ((node = attr->children) && node->type == XML_TEXT_NODE) { if ((node = attr->children) && node->type == XML_TEXT_NODE) {
clipEnd = (gchar*) node->content; clipEnd = (gchar*) node->content;
} }
} else if (!strcmp((const char*)attr->name, "clipLength")) {
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
clipLength = (gchar*) node->content;
}
} else { } else {
GST_WARNING("unsupported SMIL audio element attribute: %s", GST_WARNING("unsupported SMIL audio element attribute: %s",
attr->name); attr->name);
@ -334,6 +416,10 @@ private:
audioDescription->m_clipEnd = -1; audioDescription->m_clipEnd = -1;
} }
} }
if(clipLength)
{
audioDescription->m_clipLength = su_smil_clock_value_to_nanosec(clipLength);
}
if(idStr) if(idStr)
{ {
std::stringstream idReader(idStr); std::stringstream idReader(idStr);

View file

@ -161,6 +161,11 @@ const std::string smilPlayableStartAttrName = "clipBegin";
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
const std::string smilPlayableEndAttrName = "clipEnd"; const std::string smilPlayableEndAttrName = "clipEnd";
/*------------------------------------------------------------------------------
* The name of the attribute containing the clipLength of the Playable element.
*----------------------------------------------------------------------------*/
const std::string smilPlayableLengthAttrName = "clipLength";
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* The name of the attribute containing the relative offset of the element. * The name of the attribute containing the relative offset of the element.
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
@ -1600,6 +1605,8 @@ WebStorageClient :: acquirePlaylist(Ptr<const UniqueId>::Ref id,
= plElement->getClipStart(); = plElement->getClipStart();
Ptr<time_duration>::Ref clipEnd Ptr<time_duration>::Ref clipEnd
= plElement->getClipEnd(); = plElement->getClipEnd();
Ptr<time_duration>::Ref clipLength
= plElement->getClipLength();
Ptr<FadeInfo>::Ref fadeInfo = plElement->getFadeInfo(); Ptr<FadeInfo>::Ref fadeInfo = plElement->getFadeInfo();
@ -1652,8 +1659,13 @@ WebStorageClient :: acquirePlaylist(Ptr<const UniqueId>::Ref id,
smilPlayableNode->set_attribute( smilPlayableNode->set_attribute(
smilPlayableEndAttrName, smilPlayableEndAttrName,
*TimeConversion::timeDurationToSmilString( *TimeConversion::timeDurationToSmilString(
clipEnd )); clipEnd ));
} }
smilPlayableNode->set_attribute(
smilPlayableLengthAttrName,
*TimeConversion::timeDurationToSmilString(
clipLength ));
if (fadeInfo) { if (fadeInfo) {
Ptr<time_duration>::Ref fadeIn = fadeInfo->getFadeIn(); Ptr<time_duration>::Ref fadeIn = fadeInfo->getFadeIn();

View file

@ -168,6 +168,7 @@ class M3uPlaylist {
$offset = '???'; $offset = '???';
$clipStart = '???'; $clipStart = '???';
$clipEnd = '???'; $clipEnd = '???';
$clipLength = '???';
$uri_h = preg_replace("|--|", "&#2d;&#2d;", htmlspecialchars("$uri")); $uri_h = preg_replace("|--|", "&#2d;&#2d;", htmlspecialchars("$uri"));
if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) { if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
switch (strtolower($ext = $va[1])) { switch (strtolower($ext = $va[1])) {
@ -186,7 +187,7 @@ class M3uPlaylist {
break; break;
} }
} }
$res .= "$ind2<playlistElement id=\"$gunid\" relativeOffset=\"$offset\" clipStart=\"$clipStart\" clipEnd=\"$clipEnd\">\n". $res .= "$ind2<playlistElement id=\"$gunid\" relativeOffset=\"$offset\" clipStart=\"$clipStart\" clipEnd=\"$clipEnd\" clipLength=\"$clipLength\">\n".
$acOrPl. $acOrPl.
"$ind2</playlistElement>\n"; "$ind2</playlistElement>\n";
} }

View file

@ -424,6 +424,11 @@ class Playlist extends StoredFile {
if (PEAR::isError($endArr)) { if (PEAR::isError($endArr)) {
return $endArr; return $endArr;
} }
// get clipLength:
$lenArr = $this->md->getMetadataElement('clipLength', $elId);
if (PEAR::isError($lenArr)) {
return $lenArr;
}
$offsetId = $offArr[0]['mid']; $offsetId = $offArr[0]['mid'];
$offset = $offArr[0]['value']; $offset = $offArr[0]['value'];
// get audioClip: // get audioClip:

View file

@ -278,7 +278,8 @@ class SmilPlaylistAudioElement {
$offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val); $offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val);
$clipStart = Playlist::secondsToPlaylistTime($tree->attrs['clipStart']->val); $clipStart = Playlist::secondsToPlaylistTime($tree->attrs['clipStart']->val);
$clipEnd = Playlist::secondsToPlaylistTime($tree->attrs['clipEnd']->val); $clipEnd = Playlist::secondsToPlaylistTime($tree->attrs['clipEnd']->val);
$res = "$ind<playlistElement id=\"$plElGunid\" relativeOffset=\"$offset\" clipStart=\"$clipStart\" clipEnd=\"$clipEnd\">\n". $clipLength = Playlist::secondsToPlaylistTime($tree->attrs['clipLength']->val);
$res = "$ind<playlistElement id=\"$plElGunid\" relativeOffset=\"$offset\" clipStart=\"$clipStart\" clipEnd=\"$clipEnd\" clipLength=\"$clipLength\">\n".
"$ind2<$type id=\"$acGunid\" playlength=\"$playlength\" title=\"$title\"/>\n". "$ind2<$type id=\"$acGunid\" playlength=\"$playlength\" title=\"$title\"/>\n".
$fInfo. $fInfo.
"$ind</playlistElement>\n"; "$ind</playlistElement>\n";

View file

@ -29,7 +29,7 @@ $playlistFormat = array(
'optional'=>array('fadeInfo'), 'optional'=>array('fadeInfo'),
), ),
'attrs'=>array( 'attrs'=>array(
'required'=>array('id', 'relativeOffset', 'clipStart', 'clipEnd'), 'required'=>array('id', 'relativeOffset', 'clipStart', 'clipEnd', 'clipLength'),
), ),
), ),
'audioClip'=>array( 'audioClip'=>array(

View file

@ -26,8 +26,8 @@ $mdefs = array(
"listMethods" => array('m'=>"system.listMethods", 'p'=>NULL, 't'=>NULL), "listMethods" => array('m'=>"system.listMethods", 'p'=>NULL, 't'=>NULL),
"AddAudioClipToPlaylistMethod" => array( "AddAudioClipToPlaylistMethod" => array(
'm'=>'addAudioClipToPlaylist', 'm'=>'addAudioClipToPlaylist',
'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'audioClipId'/*string*/, 'relativeOffset'/*int*/, 'clipStart'/*int*/, 'clipEnd'/*int*/), 'p'=>array('sessionId'/*string*/, 'playlistId'/*string*/, 'audioClipId'/*string*/, 'relativeOffset'/*int*/, 'clipStart'/*int*/, 'clipEnd'/*int*/, 'clipLength'/*int*/),
't'=>array('string', 'string', 'string', 'int', 'int', 'int'), 't'=>array('string', 'string', 'string', 'int', 'int', 'int', 'int'),
'r'=>array('playlistElementId'/*string*/), 'r'=>array('playlistElementId'/*string*/),
'e'=>array( 'e'=>array(
'301'=>'invalid argument format', '301'=>'invalid argument format',

View file

@ -1301,11 +1301,11 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
switch (playable->getType()) { switch (playable->getType()) {
case Playable::AudioClipType: case Playable::AudioClipType:
outputItemPlayingNow = acquireAudioClip(playable->getId()); outputItemPlayingNow = acquireAudioClip(playable->getId());
if(false == outputPlayer->open(*outputItemPlayingNow->getUri(), (gint64)outputItemPlayingNow->getId()->getId())) if(false == outputPlayer->open(*outputItemPlayingNow->getUri(), (gint64)outputItemPlayingNow->getId()->getId(), 0L))
{ {
return false; return false;
} }
outputPlayer->start(0); outputPlayer->start();
std::cerr << "gLiveSupport: Live Mode playing audio clip '" std::cerr << "gLiveSupport: Live Mode playing audio clip '"
<< *playable->getTitle() << *playable->getTitle()
<< "'" << std::endl; << "'" << std::endl;
@ -1313,8 +1313,8 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
case Playable::PlaylistType: case Playable::PlaylistType:
outputItemPlayingNow = acquirePlaylist(playable->getId()); outputItemPlayingNow = acquirePlaylist(playable->getId());
outputPlayer->open(*outputItemPlayingNow->getUri(), (gint64)outputItemPlayingNow->getId()->getId()); outputPlayer->open(*outputItemPlayingNow->getUri(), (gint64)outputItemPlayingNow->getId()->getId(), 0L);
outputPlayer->start(0); outputPlayer->start();
std::cerr << "gLiveSupport: Live Mode playing playlist '" std::cerr << "gLiveSupport: Live Mode playing playlist '"
<< *playable->getTitle() << *playable->getTitle()
<< "'" << std::endl; << "'" << std::endl;
@ -1364,7 +1364,7 @@ GLiveSupport :: pauseOutputAudio(void)
outputPlayerIsPaused = true; outputPlayerIsPaused = true;
} else if (outputPlayerIsPaused) { } else if (outputPlayerIsPaused) {
outputPlayer->start(0); outputPlayer->start();
outputPlayerIsPaused = false; outputPlayerIsPaused = false;
} }
} }
@ -1446,8 +1446,8 @@ GLiveSupport :: playCueAudio(Ptr<Playable>::Ref playable)
switch (playable->getType()) { switch (playable->getType()) {
case Playable::AudioClipType: case Playable::AudioClipType:
cueItemPlayingNow = acquireAudioClip(playable->getId()); cueItemPlayingNow = acquireAudioClip(playable->getId());
cuePlayer->open(*cueItemPlayingNow->getUri(), (gint64)cueItemPlayingNow->getId()->getId()); cuePlayer->open(*cueItemPlayingNow->getUri(), (gint64)cueItemPlayingNow->getId()->getId(), 0L);
cuePlayer->start(0); cuePlayer->start();
std::cerr << "gLiveSupport: Cue playing audio clip '" std::cerr << "gLiveSupport: Cue playing audio clip '"
<< *playable->getTitle() << *playable->getTitle()
<< "'" << std::endl; << "'" << std::endl;
@ -1455,8 +1455,8 @@ GLiveSupport :: playCueAudio(Ptr<Playable>::Ref playable)
case Playable::PlaylistType: case Playable::PlaylistType:
cueItemPlayingNow = acquirePlaylist(playable->getId()); cueItemPlayingNow = acquirePlaylist(playable->getId());
cuePlayer->open(*cueItemPlayingNow->getUri(), (gint64)cueItemPlayingNow->getId()->getId()); cuePlayer->open(*cueItemPlayingNow->getUri(), (gint64)cueItemPlayingNow->getId()->getId(), 0L);
cuePlayer->start(0); cuePlayer->start();
std::cerr << "gLiveSupport: Cue playing playlist '" std::cerr << "gLiveSupport: Cue playing playlist '"
<< *playable->getTitle() << *playable->getTitle()
<< "'" << std::endl; << "'" << std::endl;
@ -1505,7 +1505,7 @@ GLiveSupport :: pauseCueAudio(void)
cuePlayerIsPaused = true; cuePlayerIsPaused = true;
} else if (cuePlayerIsPaused) { } else if (cuePlayerIsPaused) {
cuePlayer->start(0); cuePlayer->start();
cuePlayerIsPaused = false; cuePlayerIsPaused = false;
} }
} }
@ -1772,8 +1772,8 @@ GLiveSupport :: playTestSoundOnCue(Ptr<const Glib::ustring>::Ref oldDevice,
cuePlayer->close(); cuePlayer->close();
} }
cuePlayer->setAudioDevice(*newDevice); cuePlayer->setAudioDevice(*newDevice);
cuePlayer->open(*testAudioUrl, (gint64)0); cuePlayer->open(*testAudioUrl, 0L, 0L);
cuePlayer->start(0); cuePlayer->start();
Ptr<time_duration>::Ref sleepT(new time_duration(microseconds(10))); Ptr<time_duration>::Ref sleepT(new time_duration(microseconds(10)));
while (cuePlayer->isPlaying()) { while (cuePlayer->isPlaying()) {
runMainLoop(); runMainLoop();

View file

@ -158,8 +158,8 @@ PlaylistEvent :: start(Ptr<time_duration>::Ref offset) thr
} }
try { try {
audioPlayer->open(*playlist->getUri(), (gint64)playlist->getId()->getId()); audioPlayer->open(*playlist->getUri(), (gint64)playlist->getId()->getId(), offset->total_microseconds());
audioPlayer->start(offset->total_microseconds()); audioPlayer->start();
playLog->addPlayLogEntry(playlist->getId(), TimeConversion::now()); playLog->addPlayLogEntry(playlist->getId(), TimeConversion::now());
} catch (std::invalid_argument &e) { } catch (std::invalid_argument &e) {