Reference::Reference(const std::string &ref)
	: m_ref(ref)
{
	const std::size_t pound = ref.find('#');
	if (pound != std::string::npos) {
		m_uri = ref.substr(0, pound);
		m_pointer = Pointer(ref.substr(pound + 1));

		m_isValid = (m_uri.empty() || isURI(m_uri)) && m_pointer.isValid();
	}
}
Esempio n. 2
0
//---------------------------------------------------------------------------
//
//! \brief   check for playlist type
//
//! \author  Jo2003
//! \date    12.12.2013
//
//! \param   pl (QString&) ref. to playlist content
//
//! \return  m3u::M3U_MASTER_PL -> master playlist;
//!          m3u::M3U_MEDIA_PL  -> media playlist
//!          m3u::M3U_UNKWN_PL  -> unknown playlist type
//---------------------------------------------------------------------------
m3u::t_type QExtM3uParser::plType(const QString &pl)
{
   m3u::t_type trv = m3u::M3U_UNKWN_PL;
   QStringList sl  = pl.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
   int iM3u = 0, iTok = 0;

   // to find out which type of playlist this is we should look
   // for all URIs there.
   // If this file only contains of playlists it is a master playlist.
   // If this file only contains media URIs it is a media playlist.
   // Else it is an unknown list type.
   for (int i = 0; i < sl.count(); i++)
   {
      // no tag, but URI ...
      if (!isTag(sl.at(i)) && isURI(sl.at(i)))
      {
         // playlist extension in URI ... ?
         if (sl.at(i).indexOf("m3u", 0, Qt::CaseInsensitive) > -1)
         {
            // count ...
            iM3u ++;
         }
         else
         {
            // count ..
            iTok ++;
         }
      }
   }

   // make the final check ...
   if (iM3u && !iTok)
   {
      trv = m3u::M3U_MASTER_PL;
   }
   else if (!iM3u && iTok)
   {
      trv = m3u::M3U_MEDIA_PL;
   }

   return trv;
}
Esempio n. 3
0
//---------------------------------------------------------------------------
//
//! \brief   get stream parts / tokens from media playlist
//
//! \author  Jo2003
//! \date    12.12.2013
//
//! \param   pl (QString&) ref. to one line from playlist
//! \param   sTVec (m3u::StreamTokVector&) ref. to stream token vector
//
//! \return  0 -> ok; 1 -> playlist already handled; -1 -> any error
//---------------------------------------------------------------------------
int QExtM3uParser::getStreamToks(const QString& pl, m3u::StreamTokVector& sTVec)
{
   int              iRet      = -1;
   int              iTokCount =  0;
   QRegExp          rx;
   m3u::t_StreamTok stok;
   QStringList      sl        = pl.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);

   // reset endlist tag ...
   _bEndList = false;

   sTVec.clear();

   // can be handled on media playlist only ...
   if (plType(pl) == m3u::M3U_MEDIA_PL)
   {
      for (int i = 0; i < sl.count(); i++)
      {
         if (isTag(sl.at(i)))
         {
            if (sl.at(i).contains("#EXT-X-MEDIA-SEQUENCE:"))
            {
               rx.setPattern("#EXT-X-MEDIA-SEQUENCE:([0-9]*)");

               if (rx.indexIn(sl.at(i)) > -1)
               {
                  if (rx.cap(1).toInt() > _iMediaIndex)
                  {
                     _iMediaIndex = rx.cap(1).toInt();

                     if (_iMediaIdxUsed == -1)
                     {
                        _iMediaIdxUsed = _iMediaIndex;
                     }
                  }
                  else
                  {
                     // we already handled this playlist ...
                     iRet = 1;
                     break;
                  }
               }
            }
            else if(sl.at(i).contains("#EXT-X-TARGETDURATION:"))
            {
               rx.setPattern("#EXT-X-TARGETDURATION:([0-9]*)");

               if (rx.indexIn(sl.at(i)) > -1)
               {
                  _iTrgDuration = rx.cap(1).toInt();
               }
            }
            else if(sl.at(i).contains("#EXTINF:"))
            {
               rx.setPattern("#EXTINF:([^,]*),");

               if (rx.indexIn(sl.at(i)) > -1)
               {
                  stok.iDuration = qRound(rx.cap(1).toFloat());
               }

               rx.setPattern("#EXTINF:.*,(.*)$");

               if (rx.indexIn(sl.at(i)) > -1)
               {
                  stok.sTitle = rx.cap(1);
               }
            }
            else if(sl.at(i).contains("#EXT-X-BYTERANGE:"))
            {
               if (sl.at(i).indexOf('@') > -1)
               {
                  // offset given ...
                  rx.setPattern("#EXT-X-BYTERANGE:([0-9]*)@([0-9]*)");

                  if (rx.indexIn(sl.at(i)) > -1)
                  {
                     stok.iByteCount = rx.cap(1).toInt();
                     stok.iBOffset   = rx.cap(2).toInt();
                  }
               }
               else
               {
                  // without offset ...
                  rx.setPattern("#EXT-X-BYTERANGE:([0-9]*)");

                  if (rx.indexIn(sl.at(i)) > -1)
                  {
                     stok.iByteCount = rx.cap(1).toInt();
                     stok.iBOffset   = 0;
                  }
               }
            }
            else if(sl.at(i).contains("#EXT-X-ENDLIST"))
            {
               _bEndList = true;
            }

            // other tags not supported so far ...
         }
         else if(isURI(sl.at(i)))
         {
            iTokCount ++;
            if ((_iMediaIndex + iTokCount) > _iMediaIdxUsed)
            {
               stok.sUri = completeUri(sl.at(i).simplified());
               _iMediaIdxUsed ++;
               sTVec.append(stok);
            }

            // reset stream structure ...
            stok.iBOffset   = -1;
            stok.iByteCount = -1;
            stok.iDuration  = -1;
            stok.sTitle     = "";
            stok.sUri       = "";
         }
      }
   }

   if (!sTVec.isEmpty() && (iRet != 1))
   {
      iRet = 0;
   }

   return iRet;
}
Esempio n. 4
0
//---------------------------------------------------------------------------
//
//! \brief   get available streams from master playlist
//
//! \author  Jo2003
//! \date    12.12.2013
//
//! \param   pl (QString&) ref. to one line from playlist
//! \param   sVec (m3u::StreamVector&) ref. to stream vector
//
//! \return  0 -> ok; -1 -> any error
//---------------------------------------------------------------------------
int QExtM3uParser::getStreams(const QString& pl, m3u::StreamVector& sVec)
{
   int           iRet   = -1;
   QRegExp       rx;
   m3u::t_Stream stream;
   QStringList   sl     = pl.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);

   sVec.clear();

   // can be handled on master playlist only ...
   if (plType(pl) == m3u::M3U_MASTER_PL)
   {
      for (int i = 0; i < sl.count(); i++)
      {
         if (isTag(sl.at(i)))
         {
            // get stream info ...
            if (sl.at(i).indexOf("#EXT-X-STREAM-INF") > -1)
            {
               rx.setPattern("PROGRAM-ID=([0-9]*)");

               if (rx.indexIn(sl.at(i)) > -1)
               {
                  stream.iId = rx.cap(1).toInt();
               }

               rx.setPattern("RESOLUTION=([0-9]*)x([0-9]*)");

               if (rx.indexIn(sl.at(i)) > -1)
               {
                  stream.szRes.setWidth(rx.cap(1).toInt());
                  stream.szRes.setHeight(rx.cap(2).toInt());
               }

               rx.setPattern("BANDWIDTH=([0-9]*)");

               if (rx.indexIn(sl.at(i)) > -1)
               {
                  stream.iBandWidth = rx.cap(1).toInt();
               }
            }

            // other tags not supported so far ...
         }
         else if(isURI(sl.at(i)))
         {
            // get url of media playlist ...
            stream.sUri = completeUri(sl.at(i).simplified());

            // add element to vector ...
            sVec.append(stream);

            // reset stream structure ...
            stream.iBandWidth = -1;
            stream.iId        = -1;
            stream.szRes      = QSize();
            stream.sUri       = "";
         }
      }
   }

   if (!sVec.isEmpty())
   {
      iRet = 0;
   }

   return iRet;
}