DTC::LiveStreamInfoList *HTTPLiveStream::GetLiveStreamInfoList(const QString &FileName) { DTC::LiveStreamInfoList *infoList = new DTC::LiveStreamInfoList(); QString sql = "SELECT id FROM livestream "; if (!FileName.isEmpty()) sql += "WHERE sourcefile LIKE :FILENAME "; sql += "ORDER BY lastmodified DESC;"; MSqlQuery query(MSqlQuery::InitCon()); query.prepare(sql); if (!FileName.isEmpty()) query.bindValue(":FILENAME", QString("%%1%").arg(FileName)); if (!query.exec()) { LOG(VB_GENERAL, LOG_ERR, SLOC + "Unable to get list of Live Streams"); return infoList; } DTC::LiveStreamInfo *info = NULL; HTTPLiveStream *hls = NULL; while (query.next()) { hls = new HTTPLiveStream(query.value(0).toUInt()); info = infoList->AddNewLiveStreamInfo(); hls->GetLiveStreamInfo(info); delete hls; } return infoList; }
DTC::LiveStreamInfo *HTTPLiveStream::StopStream(int id) { MSqlQuery query(MSqlQuery::InitCon()); query.prepare( "UPDATE livestream " "SET status = :STATUS " "WHERE id = :STREAMID; "); query.bindValue(":STATUS", (int)kHLSStatusStopping); query.bindValue(":STREAMID", id); if (!query.exec()) { LOG(VB_GENERAL, LOG_ERR, SLOC + QString("Unable to remove mark stream stopped for stream %1.") .arg(id)); return NULL; } HTTPLiveStream *hls = new HTTPLiveStream(id); if (!hls) return NULL; MythTimer statusTimer; int delay = 250000; statusTimer.start(); HTTPLiveStreamStatus status = hls->GetDBStatus(); while ((status != kHLSStatusStopped) && (status != kHLSStatusCompleted) && (status != kHLSStatusErrored) && ((statusTimer.elapsed() / 1000) < 30)) { delay = (int)(delay * 1.5); usleep(delay); status = hls->GetDBStatus(); } hls->LoadFromDB(); DTC::LiveStreamInfo *pLiveStreamInfo = hls->GetLiveStreamInfo(); delete hls; return pLiveStreamInfo; }
DTC::LiveStreamInfo *Content::GetLiveStream( int nId ) { HTTPLiveStream *hls = new HTTPLiveStream(nId); if (!hls) { LOG( VB_UPNP, LOG_ERR, QString("GetLiveStream - for stream id %1 failed").arg( nId )); return NULL; } DTC::LiveStreamInfo *hlsInfo = hls->GetLiveStreamInfo(); if (!hlsInfo) { LOG( VB_UPNP, LOG_ERR, QString("HLS::GetLiveStreamInfo - for stream id %1 failed") .arg( nId )); return NULL; } delete hls; return hlsInfo; }
DTC::LiveStreamInfo *Content::AddLiveStream( const QString &sStorageGroup, const QString &sFileName, const QString &sHostName, int nMaxSegments, int nWidth, int nHeight, int nBitrate, int nAudioBitrate, int nSampleRate ) { QString sGroup = sStorageGroup; if (sGroup.isEmpty()) { LOG(VB_UPNP, LOG_WARNING, "AddLiveStream - StorageGroup missing... using 'Default'"); sGroup = "Default"; } if (sFileName.isEmpty()) { QString sMsg ( "AddLiveStream - FileName missing." ); LOG(VB_UPNP, LOG_ERR, sMsg); throw sMsg; } // ------------------------------------------------------------------ // Search for the filename // ------------------------------------------------------------------ QString sFullFileName; if (sHostName.isEmpty() || sHostName == gCoreContext->GetHostName()) { StorageGroup storage( sGroup ); sFullFileName = storage.FindFile( sFileName ); if (sFullFileName.isEmpty()) { LOG(VB_UPNP, LOG_ERR, QString("AddLiveStream - Unable to find %1.").arg(sFileName)); return NULL; } } else { sFullFileName = gCoreContext->GenMythURL(sHostName, 0, sFileName, sStorageGroup); } HTTPLiveStream *hls = new HTTPLiveStream(sFullFileName, nWidth, nHeight, nBitrate, nAudioBitrate, nMaxSegments, 10, 32000, nSampleRate); if (!hls) { LOG(VB_UPNP, LOG_ERR, "AddLiveStream - Unable to create HTTPLiveStream."); return NULL; } DTC::LiveStreamInfo *lsInfo = hls->StartStream(); delete hls; return lsInfo; }
bool HTTPLiveStream::RemoveStream(int id) { MSqlQuery query(MSqlQuery::InitCon()); query.prepare( "SELECT startSegment, segmentCount " "FROM livestream " "WHERE id = :STREAMID; "); query.bindValue(":STREAMID", id); if (!query.exec() || !query.next()) { LOG(VB_RECORD, LOG_ERR, "Error selecting stream info in RemoveStream"); return false; } HTTPLiveStream *hls = new HTTPLiveStream(id); if (hls->GetDBStatus() == kHLSStatusRunning) { HTTPLiveStream::StopStream(id); } QString thisFile; int startSegment = query.value(0).toInt(); int segmentCount = query.value(1).toInt(); for (int x = 0; x < segmentCount; ++x) { thisFile = hls->GetFilename(startSegment + x); if (!thisFile.isEmpty() && !QFile::remove(thisFile)) LOG(VB_GENERAL, LOG_ERR, SLOC + QString("Unable to delete %1.").arg(thisFile)); thisFile = hls->GetFilename(startSegment + x, false, true); if (!thisFile.isEmpty() && !QFile::remove(thisFile)) LOG(VB_GENERAL, LOG_ERR, SLOC + QString("Unable to delete %1.").arg(thisFile)); } thisFile = hls->GetMetaPlaylistName(); if (!thisFile.isEmpty() && !QFile::remove(thisFile)) LOG(VB_GENERAL, LOG_ERR, SLOC + QString("Unable to delete %1.").arg(thisFile)); thisFile = hls->GetPlaylistName(); if (!thisFile.isEmpty() && !QFile::remove(thisFile)) LOG(VB_GENERAL, LOG_ERR, SLOC + QString("Unable to delete %1.").arg(thisFile)); thisFile = hls->GetPlaylistName(true); if (!thisFile.isEmpty() && !QFile::remove(thisFile)) LOG(VB_GENERAL, LOG_ERR, SLOC + QString("Unable to delete %1.").arg(thisFile)); thisFile = hls->GetHTMLPageName(); if (!thisFile.isEmpty() && !QFile::remove(thisFile)) LOG(VB_GENERAL, LOG_ERR, SLOC + QString("Unable to delete %1.").arg(thisFile)); query.prepare( "DELETE FROM livestream " "WHERE id = :STREAMID; "); query.bindValue(":STREAMID", id); if (!query.exec()) LOG(VB_RECORD, LOG_ERR, "Error deleting stream info in RemoveStream"); delete hls; return true; }