added support for playlist element length
This commit is contained in:
parent
1f05438448
commit
9b88996d92
18 changed files with 231 additions and 61 deletions
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -168,6 +168,7 @@ class M3uPlaylist {
|
||||||
$offset = '???';
|
$offset = '???';
|
||||||
$clipStart = '???';
|
$clipStart = '???';
|
||||||
$clipEnd = '???';
|
$clipEnd = '???';
|
||||||
|
$clipLength = '???';
|
||||||
$uri_h = preg_replace("|--|", "d;d;", htmlspecialchars("$uri"));
|
$uri_h = preg_replace("|--|", "d;d;", 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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue