MythTV  0.26-pre
content.cpp
Go to the documentation of this file.
00001 
00002 // Program Name: content.cpp
00003 // Created     : Mar. 7, 2011
00004 //
00005 // Copyright (c) 2011 David Blain <dblain@mythtv.org>
00006 //                                          
00007 // This library is free software; you can redistribute it and/or 
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 2.1 of the License, or at your option any later version of the LGPL.
00011 //
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 // Lesser General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public
00018 // License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00019 //
00021 
00022 #include "content.h"
00023 
00024 #include <QDir>
00025 #include <QImage>
00026 #include <math.h>
00027 
00028 #include <compat.h>
00029 
00030 #include "mythcorecontext.h"
00031 #include "storagegroup.h"
00032 #include "programinfo.h"
00033 #include "previewgenerator.h"
00034 #include "backendutil.h"
00035 #include "httprequest.h"
00036 #include "serviceUtil.h"
00037 #include "mythmiscutil.h"
00038 #include "mythdownloadmanager.h"
00039 #include "metadataimagehelper.h"
00040 #include "videometadatalistmanager.h"
00041 #include "HLS/httplivestream.h"
00042 
00044 //
00046 
00047 QFileInfo Content::GetFile( const QString &sStorageGroup,
00048                             const QString &sFileName )
00049 {
00050     QString sGroup = sStorageGroup;
00051 
00052     if (sGroup.isEmpty())
00053     {
00054         LOG(VB_UPNP, LOG_WARNING,
00055             "GetFile - StorageGroup missing... using 'Default'");
00056         sGroup = "Default";
00057     }
00058 
00059     if (sFileName.isEmpty())
00060     {
00061         QString sMsg ( "GetFile - FileName missing." );
00062 
00063         LOG(VB_UPNP, LOG_ERR, sMsg);
00064 
00065         throw sMsg;
00066     }
00067 
00068     // ------------------------------------------------------------------
00069     // Search for the filename
00070     // ------------------------------------------------------------------
00071 
00072     StorageGroup storage( sGroup );
00073     QString sFullFileName = storage.FindFile( sFileName );
00074 
00075     if (sFullFileName.isEmpty())
00076     {
00077         LOG(VB_UPNP, LOG_ERR,
00078             QString("GetFile - Unable to find %1.").arg(sFileName));
00079 
00080         return QFileInfo();
00081     }
00082 
00083     // ----------------------------------------------------------------------
00084     // check to see if the file (still) exists
00085     // ----------------------------------------------------------------------
00086 
00087     if (QFile::exists( sFullFileName ))
00088     {
00089         return QFileInfo( sFullFileName );
00090     }
00091 
00092     LOG(VB_UPNP, LOG_ERR,
00093         QString("GetFile - File Does not exist %1.").arg(sFullFileName));
00094 
00095     return QFileInfo();
00096 }
00097 
00099 //
00101 
00102 QFileInfo Content::GetImageFile( const QString &sStorageGroup,
00103                             const QString &sFileName,
00104                             int nWidth,
00105                             int nHeight)
00106 {
00107     QString sGroup = sStorageGroup;
00108 
00109     if (sGroup.isEmpty())
00110     {
00111         LOG(VB_UPNP, LOG_WARNING,
00112             "GetFile - StorageGroup missing... using 'Default'");
00113         sGroup = "Default";
00114     }
00115 
00116     if (sFileName.isEmpty())
00117     {
00118         QString sMsg ( "GetFile - FileName missing." );
00119 
00120         LOG(VB_UPNP, LOG_ERR, sMsg);
00121 
00122         throw sMsg;
00123     }
00124 
00125     // ------------------------------------------------------------------
00126     // Search for the filename
00127     // ------------------------------------------------------------------
00128 
00129     StorageGroup storage( sGroup );
00130     QString sFullFileName = storage.FindFile( sFileName );
00131 
00132     if (sFullFileName.isEmpty())
00133     {
00134         LOG(VB_UPNP, LOG_ERR,
00135             QString("GetImageFile - Unable to find %1.").arg(sFileName));
00136 
00137         return QFileInfo();
00138     }
00139 
00140     // ----------------------------------------------------------------------
00141     // check to see if the file (still) exists
00142     // ----------------------------------------------------------------------
00143 
00144     if ((nWidth == 0) && (nHeight == 0))
00145     {
00146         if (QFile::exists( sFullFileName ))
00147         {
00148             return QFileInfo( sFullFileName );
00149         }
00150 
00151         LOG(VB_UPNP, LOG_ERR,
00152             QString("GetImageFile - File Does not exist %1.").arg(sFullFileName));
00153 
00154         return QFileInfo();
00155     }
00156 
00157     QString sNewFileName = QString( "%1.%2x%3.jpg" )
00158                               .arg( sFullFileName )
00159                               .arg( nWidth    )
00160                               .arg( nHeight   );
00161 
00162     // ----------------------------------------------------------------------
00163     // check to see if image is already created.
00164     // ----------------------------------------------------------------------
00165 
00166     if (QFile::exists( sNewFileName ))
00167         return QFileInfo( sNewFileName );
00168 
00169     // ----------------------------------------------------------------------
00170     // Must generate Generate Image and save.
00171     // ----------------------------------------------------------------------
00172 
00173     float fAspect = 0.0;
00174 
00175     QImage *pImage = new QImage( sFullFileName);
00176 
00177     if (!pImage)
00178         return QFileInfo();
00179 
00180     if (fAspect <= 0)
00181            fAspect = (float)(pImage->width()) / pImage->height();
00182 
00183     if ( nWidth == 0 )
00184         nWidth = (int)rint(nHeight * fAspect);
00185 
00186     if ( nHeight == 0 )
00187         nHeight = (int)rint(nWidth / fAspect);
00188 
00189     QImage img = pImage->scaled( nWidth, nHeight, Qt::IgnoreAspectRatio,
00190                                 Qt::SmoothTransformation);
00191 
00192     QByteArray fname = sNewFileName.toAscii();
00193     img.save( fname.constData(), "JPG", 60 );
00194 
00195     delete pImage;
00196 
00197     return QFileInfo( sNewFileName );
00198 }
00199 
00201 //
00203 
00204 QStringList Content::GetFileList( const QString &sStorageGroup )
00205 {
00206 
00207     if (sStorageGroup.isEmpty())
00208     {
00209         QString sMsg( "GetFileList - StorageGroup missing.");
00210         LOG(VB_UPNP, LOG_ERR, sMsg);
00211 
00212         throw sMsg;
00213     }
00214 
00215     StorageGroup sgroup(sStorageGroup);
00216 
00217     return sgroup.GetFileList("", true);
00218 }
00219 
00221 //
00223 
00224 QFileInfo Content::GetRecordingArtwork ( const QString   &sType,
00225                                          const QString   &sInetref,
00226                                          int nSeason,
00227                                          int nWidth,
00228                                          int nHeight)
00229 {
00230     ArtworkMap map = GetArtwork(sInetref, nSeason);
00231 
00232     VideoArtworkType type = kArtworkCoverart;
00233     QString sgroup;
00234 
00235     if (sType.toLower() == "coverart")
00236     {
00237         sgroup = "Coverart";
00238         type = kArtworkCoverart;
00239     }
00240     else if (sType.toLower() == "fanart")
00241     {
00242         sgroup = "Fanart";
00243         type = kArtworkFanart;
00244     }
00245     else if (sType.toLower() == "banner")
00246     {
00247         sgroup = "Banners";
00248         type = kArtworkBanner;
00249     }
00250 
00251     QUrl url(map.value(type).url);
00252     QString sFileName = url.path();
00253 
00254     return GetImageFile( sgroup, sFileName, nWidth, nHeight);
00255 }
00256 
00258 //
00260 
00261 DTC::ArtworkInfoList* Content::GetRecordingArtworkList( int              nChanId,
00262                                                         const QDateTime &dStartTime  )
00263 {
00264     if (nChanId <= 0 || !dStartTime.isValid())
00265         throw( QString("Channel ID or StartTime appears invalid."));
00266 
00267     ProgramInfo pInfo = ProgramInfo(nChanId, dStartTime);
00268 
00269     return GetProgramArtworkList(pInfo.GetInetRef(), pInfo.GetSeason());
00270 }
00271 
00272 DTC::ArtworkInfoList* Content::GetProgramArtworkList( const QString &sInetref,
00273                                                       int            nSeason  )
00274 {
00275     DTC::ArtworkInfoList *pArtwork = new DTC::ArtworkInfoList();
00276 
00277     FillArtworkInfoList (pArtwork, sInetref, nSeason);
00278 
00279     return pArtwork;
00280 }
00282 //
00284 
00285 QFileInfo Content::GetVideoArtwork( const QString &sType,
00286                                     int nId, int nWidth, int nHeight )
00287 {
00288     LOG(VB_UPNP, LOG_INFO, QString("GetVideoArtwork ID = %1").arg(nId));
00289 
00290     QString sgroup = "Coverart";
00291     QString column = "coverfile";
00292 
00293     if (sType.toLower() == "coverart")
00294     {
00295         sgroup = "Coverart";
00296         column = "coverfile";
00297     }
00298     else if (sType.toLower() == "fanart")
00299     {
00300         sgroup = "Fanart";
00301         column = "fanart";
00302     }
00303     else if (sType.toLower() == "banner")
00304     {
00305         sgroup = "Banners";
00306         column = "banner";
00307     }
00308     else if (sType.toLower() == "screenshot")
00309     {
00310         sgroup = "Screenshots";
00311         column = "screenshot";
00312     }
00313 
00314     // ----------------------------------------------------------------------
00315     // Read Video artwork file path from database
00316     // ----------------------------------------------------------------------
00317 
00318     MSqlQuery query(MSqlQuery::InitCon());
00319 
00320     QString querystr = QString("SELECT %1 FROM videometadata WHERE "
00321                                "intid = :ITEMID").arg(column);
00322 
00323     query.prepare(querystr);
00324     query.bindValue(":ITEMID", nId);
00325 
00326     if (!query.exec())
00327         MythDB::DBError("GetVideoArtwork ", query);
00328 
00329     if (!query.next())
00330         return QFileInfo();
00331 
00332     QString sFileName = query.value(0).toString();
00333 
00334     return GetImageFile( sgroup, sFileName, nWidth, nHeight );
00335 }
00336 
00338 //
00340 
00341 QFileInfo Content::GetAlbumArt( int nId, int nWidth, int nHeight )
00342 {
00343     QString sFullFileName;
00344 
00345     // ----------------------------------------------------------------------
00346     // Read AlbumArt file path from database
00347     // ----------------------------------------------------------------------
00348 
00349     MSqlQuery query(MSqlQuery::InitCon());
00350 
00351     query.prepare("SELECT CONCAT_WS('/', music_directories.path, "
00352                   "music_albumart.filename) FROM music_albumart "
00353                   "LEFT JOIN music_directories ON "
00354                   "music_directories.directory_id=music_albumart.directory_id "
00355                   "WHERE music_albumart.albumart_id = :ARTID;");
00356 
00357     query.bindValue(":ARTID", nId );
00358 
00359     if (!query.exec())
00360         MythDB::DBError("Select ArtId", query);
00361 
00362     QString sMusicBasePath = gCoreContext->GetSetting("MusicLocation", "");
00363 
00364     if (query.next())
00365     {
00366         sFullFileName = QString( "%1/%2" )
00367                         .arg( sMusicBasePath )
00368                         .arg( query.value(0).toString() );
00369     }
00370 
00371     if (!QFile::exists( sFullFileName ))
00372         return QFileInfo();
00373 
00374     if ((nWidth == 0) && (nHeight == 0))
00375         return QFileInfo( sFullFileName );
00376 
00377     QString sNewFileName = QString( "%1.%2x%3.png" )
00378                               .arg( sFullFileName )
00379                               .arg( nWidth    )
00380                               .arg( nHeight   );
00381 
00382     // ----------------------------------------------------------------------
00383     // check to see if albumart image is already created.
00384     // ----------------------------------------------------------------------
00385 
00386     if (QFile::exists( sNewFileName ))
00387         return QFileInfo( sNewFileName );
00388 
00389     // ----------------------------------------------------------------------
00390     // Must generate Albumart Image, Generate Image and save.
00391     // ----------------------------------------------------------------------
00392 
00393     float fAspect = 0.0;
00394 
00395     QImage *pImage = new QImage( sFullFileName);
00396 
00397     if (!pImage)
00398         return QFileInfo();
00399 
00400     if (fAspect <= 0)
00401            fAspect = (float)(pImage->width()) / pImage->height();
00402 
00403     if ( nWidth == 0 )
00404         nWidth = (int)rint(nHeight * fAspect);
00405 
00406     if ( nHeight == 0 )
00407         nHeight = (int)rint(nWidth / fAspect);
00408 
00409     QImage img = pImage->scaled( nWidth, nHeight, Qt::IgnoreAspectRatio,
00410                                 Qt::SmoothTransformation);
00411 
00412     QByteArray fname = sNewFileName.toAscii();
00413     img.save( fname.constData(), "PNG" );
00414 
00415     delete pImage;
00416 
00417     return QFileInfo( sNewFileName );
00418 }
00419 
00421 //
00423 
00424 QFileInfo Content::GetPreviewImage(        int        nChanId,
00425                                      const QDateTime &dtStartTime,
00426                                            int        nWidth,
00427                                            int        nHeight,
00428                                            int        nSecsIn )
00429 {
00430     if (!dtStartTime.isValid())
00431     {
00432         QString sMsg = QString("GetPreviewImage: bad start time '%1'")
00433                           .arg( dtStartTime.toString() );
00434 
00435         LOG(VB_GENERAL, LOG_ERR, sMsg);
00436 
00437         throw sMsg;
00438     }
00439 
00440     // ----------------------------------------------------------------------
00441     // Read Recording From Database
00442     // ----------------------------------------------------------------------
00443 
00444     ProgramInfo pginfo( (uint)nChanId, dtStartTime);
00445 
00446     if (!pginfo.GetChanID())
00447     {
00448         LOG(VB_GENERAL, LOG_ERR,
00449             QString( "GetPreviewImage: no recording for start time '%1'" )
00450                                  .arg( dtStartTime.toString() ));
00451         return QFileInfo();
00452     }
00453 
00454     if ( pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower())
00455     {
00456         QString sMsg =
00457             QString("GetPreviewImage: Wrong Host '%1' request from '%2'")
00458                           .arg( gCoreContext->GetHostName())
00459                           .arg( pginfo.GetHostname() );
00460 
00461         LOG(VB_UPNP, LOG_ERR, sMsg);
00462 
00463         throw HttpRedirectException( pginfo.GetHostname() );
00464     }
00465 
00466     QString sFileName = GetPlaybackURL(&pginfo);
00467 
00468     // ----------------------------------------------------------------------
00469     // check to see if default preview image is already created.
00470     // ----------------------------------------------------------------------
00471 
00472     QString sPreviewFileName;
00473 
00474     if (nSecsIn <= 0)
00475     {
00476         nSecsIn = -1;
00477         sPreviewFileName = sFileName + ".png";
00478     }
00479     else
00480     {
00481         sPreviewFileName = QString("%1.%2.png").arg(sFileName).arg(nSecsIn);
00482     }
00483 
00484     if (!QFile::exists( sPreviewFileName ))
00485     {
00486         // ------------------------------------------------------------------
00487         // Must generate Preview Image, Generate Image and save.
00488         // ------------------------------------------------------------------
00489         if (!pginfo.IsLocal() && sFileName.left(1) == "/")
00490             pginfo.SetPathname(sFileName);
00491 
00492         if (!pginfo.IsLocal())
00493             return QFileInfo();
00494 
00495         PreviewGenerator *previewgen = new PreviewGenerator( &pginfo, 
00496                                                              QString(), 
00497                                                              PreviewGenerator::kLocal);
00498         previewgen->SetPreviewTimeAsSeconds( nSecsIn          );
00499         previewgen->SetOutputFilename      ( sPreviewFileName );
00500 
00501         bool ok = previewgen->Run();
00502 
00503         previewgen->deleteLater();
00504 
00505         if (!ok)
00506             return QFileInfo();
00507     }
00508 
00509     float fAspect = 0.0;
00510 
00511     QImage *pImage = new QImage(sPreviewFileName);
00512 
00513     if (!pImage)
00514         return QFileInfo();
00515 
00516     if (fAspect <= 0)
00517         fAspect = (float)(pImage->width()) / pImage->height();
00518 
00519     if (fAspect == 0)
00520     {
00521         delete pImage;
00522         return QFileInfo();
00523     }
00524 
00525     bool bDefaultPixmap = (nWidth == 0) && (nHeight == 0);
00526 
00527     if ( nWidth == 0 )
00528         nWidth = (int)rint(nHeight * fAspect);
00529 
00530     if ( nHeight == 0 )
00531         nHeight = (int)rint(nWidth / fAspect);
00532 
00533     QString sNewFileName;
00534 
00535     if (bDefaultPixmap)
00536         sNewFileName = sPreviewFileName;
00537     else
00538         sNewFileName = QString( "%1.%2.%3x%4.png" )
00539                           .arg( sFileName )
00540                           .arg( nSecsIn   )
00541                           .arg( nWidth    )
00542                           .arg( nHeight   );
00543 
00544     // ----------------------------------------------------------------------
00545     // check to see if scaled preview image is already created.
00546     // ----------------------------------------------------------------------
00547 
00548     if (QFile::exists( sNewFileName ))
00549     {
00550         delete pImage;
00551         return QFileInfo( sNewFileName );
00552     }
00553 
00554     PreviewGenerator *previewgen = new PreviewGenerator( &pginfo,
00555                                                          QString(),
00556                                                          PreviewGenerator::kLocal);
00557     previewgen->SetPreviewTimeAsSeconds( nSecsIn             );
00558     previewgen->SetOutputFilename      ( sNewFileName        );
00559     previewgen->SetOutputSize          (QSize(nWidth,nHeight));
00560 
00561     bool ok = previewgen->Run();
00562 
00563     previewgen->deleteLater();
00564 
00565     if (!ok)
00566         return QFileInfo();
00567 
00568     delete pImage;
00569 
00570     return QFileInfo( sNewFileName );
00571 }
00572 
00574 //
00576 
00577 QFileInfo Content::GetRecording( int              nChanId,
00578                                  const QDateTime &dtStartTime )
00579 {
00580     if (!dtStartTime.isValid())
00581         throw( "StartTime is invalid" );
00582 
00583     // ------------------------------------------------------------------
00584     // Read Recording From Database
00585     // ------------------------------------------------------------------
00586 
00587     ProgramInfo pginfo( (uint)nChanId, dtStartTime );
00588 
00589     if (!pginfo.GetChanID())
00590     {
00591         LOG( VB_UPNP, LOG_ERR, QString("GetRecording - for %1, %2 failed")
00592                                     .arg( nChanId )
00593                                     .arg( dtStartTime.toString() ));
00594         return QFileInfo();
00595     }
00596 
00597     if ( pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower())
00598     {
00599         // We only handle requests for local resources
00600 
00601         QString sMsg =
00602             QString("GetRecording: Wrong Host '%1' request from '%2'.")
00603                           .arg( gCoreContext->GetHostName())
00604                           .arg( pginfo.GetHostname() );
00605 
00606         LOG(VB_UPNP, LOG_ERR, sMsg);
00607 
00608         throw HttpRedirectException( pginfo.GetHostname() );
00609     }
00610 
00611     QString sFileName( GetPlaybackURL(&pginfo) );
00612 
00613     // ----------------------------------------------------------------------
00614     // check to see if the file exists
00615     // ----------------------------------------------------------------------
00616 
00617     if (QFile::exists( sFileName ))
00618         return QFileInfo( sFileName );
00619 
00620     return QFileInfo();
00621 }
00622 
00624 //
00626 
00627 QFileInfo Content::GetMusic( int nId )
00628 {
00629     QString sBasePath = gCoreContext->GetSetting( "MusicLocation", "");
00630     QString sFileName;
00631 
00632     // ----------------------------------------------------------------------
00633     // Load Track's FileName
00634     // ----------------------------------------------------------------------
00635 
00636     MSqlQuery query(MSqlQuery::InitCon());
00637 
00638     if (query.isConnected())
00639     {
00640         query.prepare("SELECT CONCAT_WS('/', music_directories.path, "
00641                        "music_songs.filename) AS filename FROM music_songs "
00642                        "LEFT JOIN music_directories ON "
00643                          "music_songs.directory_id="
00644                          "music_directories.directory_id "
00645                        "WHERE music_songs.song_id = :KEY");
00646 
00647         query.bindValue(":KEY", nId );
00648 
00649         if (!query.exec())
00650         {
00651             MythDB::DBError("GetMusic()", query);
00652             return QFileInfo();
00653         }
00654 
00655         if (query.next())
00656         {
00657             sFileName = QString( "%1/%2" )
00658                            .arg( sBasePath )
00659                            .arg( query.value(0).toString() );
00660         }
00661     }
00662 
00663     // ----------------------------------------------------------------------
00664     // check to see if the file exists
00665     // ----------------------------------------------------------------------
00666 
00667     if (QFile::exists( sFileName ))
00668         return QFileInfo( sFileName );
00669 
00670     return QFileInfo();
00671 }
00672 
00674 //
00676 
00677 QFileInfo Content::GetVideo( int nId )
00678 {
00679     QString sFileName;
00680 
00681     // ----------------------------------------------------------------------
00682     // Load Track's FileName
00683     // ----------------------------------------------------------------------
00684 
00685     MSqlQuery query(MSqlQuery::InitCon());
00686 
00687     if (query.isConnected())
00688     {
00689         query.prepare("SELECT filename FROM videometadata WHERE intid = :KEY" );
00690         query.bindValue(":KEY", nId );
00691 
00692         if (!query.exec())
00693         {
00694             MythDB::DBError("GetVideo()", query);
00695             return QFileInfo();
00696         }
00697 
00698         if (query.next())
00699             sFileName = query.value(0).toString();
00700     }
00701 
00702     if (sFileName.isEmpty())
00703         return QFileInfo();
00704 
00705     if (!QFile::exists( sFileName ))
00706         return GetFile( "Videos", sFileName );
00707 
00708     return QFileInfo( sFileName );
00709 }
00710 
00712 //
00714 
00715 QString Content::GetHash( const QString &sStorageGroup,
00716                           const QString &sFileName )
00717 {
00718     if ((sFileName.isEmpty()) ||
00719         (sFileName.contains("/../")) ||
00720         (sFileName.startsWith("../")))
00721     {
00722         LOG(VB_GENERAL, LOG_ERR,
00723             QString("ERROR checking for file, filename '%1' "
00724                     "fails sanity checks").arg(sFileName));
00725         return QString();
00726     }
00727 
00728     QString storageGroup = "Default";
00729 
00730     if (!sStorageGroup.isEmpty())
00731         storageGroup = sStorageGroup;
00732 
00733     StorageGroup sgroup(storageGroup, gCoreContext->GetHostName());
00734 
00735     QString fullname = sgroup.FindFile(sFileName);
00736     QString hash = FileHash(fullname);
00737 
00738     if (hash == "NULL")
00739         return QString();
00740 
00741     return hash;
00742 }
00743 
00745 //
00747 
00748 bool Content::DownloadFile( const QString &sURL, const QString &sStorageGroup )
00749 {
00750     QFileInfo finfo(sURL);
00751     QString filename = finfo.fileName();
00752     StorageGroup sgroup(sStorageGroup, gCoreContext->GetHostName(), false);
00753     QString outDir = sgroup.FindNextDirMostFree();
00754     QString outFile;
00755 
00756     if (outDir.isEmpty())
00757     {
00758         LOG(VB_GENERAL, LOG_ERR,
00759             QString("Unable to determine directory "
00760                     "to write to in %1 write command").arg(sURL));
00761         return false;
00762     }
00763 
00764     if ((filename.contains("/../")) ||
00765         (filename.startsWith("../")))
00766     {
00767         LOG(VB_GENERAL, LOG_ERR,
00768             QString("ERROR: %1 write filename '%2' does not "
00769                     "pass sanity checks.") .arg(sURL).arg(filename));
00770         return false;
00771     }
00772 
00773     outFile = outDir + "/" + filename;
00774 
00775     if (GetMythDownloadManager()->download(sURL, outFile))
00776         return true;
00777 
00778     return false;
00779 }
00780 
00782 //
00784 
00785 DTC::LiveStreamInfo *Content::AddLiveStream( const QString   &sStorageGroup,
00786                                              const QString   &sFileName,
00787                                              const QString   &sHostName,
00788                                              int              nMaxSegments,
00789                                              int              nWidth,
00790                                              int              nHeight,
00791                                              int              nBitrate,
00792                                              int              nAudioBitrate,
00793                                              int              nSampleRate )
00794 {
00795     QString sGroup = sStorageGroup;
00796 
00797     if (sGroup.isEmpty())
00798     {
00799         LOG(VB_UPNP, LOG_WARNING,
00800             "AddLiveStream - StorageGroup missing... using 'Default'");
00801         sGroup = "Default";
00802     }
00803 
00804     if (sFileName.isEmpty())
00805     {
00806         QString sMsg ( "AddLiveStream - FileName missing." );
00807 
00808         LOG(VB_UPNP, LOG_ERR, sMsg);
00809 
00810         throw sMsg;
00811     }
00812 
00813     // ------------------------------------------------------------------
00814     // Search for the filename
00815     // ------------------------------------------------------------------
00816 
00817     QString sFullFileName;
00818     if (sHostName.isEmpty() || sHostName == gCoreContext->GetHostName())
00819     {
00820         StorageGroup storage( sGroup );
00821         sFullFileName = storage.FindFile( sFileName );
00822 
00823         if (sFullFileName.isEmpty())
00824         {
00825             LOG(VB_UPNP, LOG_ERR,
00826                 QString("AddLiveStream - Unable to find %1.").arg(sFileName));
00827 
00828             return NULL;
00829         }
00830     }
00831     else
00832     {
00833         sFullFileName =
00834             gCoreContext->GenMythURL(sHostName, 0, sFileName, sStorageGroup);
00835     }
00836 
00837     HTTPLiveStream *hls = new
00838         HTTPLiveStream(sFullFileName, nWidth, nHeight, nBitrate, nAudioBitrate,
00839                        nMaxSegments, 10, 32000, nSampleRate);
00840 
00841     if (!hls)
00842     {
00843         LOG(VB_UPNP, LOG_ERR,
00844             "AddLiveStream - Unable to create HTTPLiveStream.");
00845         return NULL;
00846     }
00847 
00848     DTC::LiveStreamInfo *lsInfo = hls->StartStream();
00849 
00850     delete hls;
00851 
00852     return lsInfo;
00853 }
00854 
00856 //
00858 
00859 bool Content::RemoveLiveStream( int nId )
00860 {
00861     return HTTPLiveStream::RemoveStream(nId);
00862 }
00863 
00865 //
00867 
00868 DTC::LiveStreamInfo *Content::StopLiveStream( int nId )
00869 {
00870     return HTTPLiveStream::StopStream(nId);
00871 }
00872 
00874 //
00876 
00877 DTC::LiveStreamInfo *Content::GetLiveStream( int nId )
00878 {
00879     HTTPLiveStream *hls = new HTTPLiveStream(nId);
00880 
00881     if (!hls)
00882     {
00883         LOG( VB_UPNP, LOG_ERR,
00884              QString("GetLiveStream - for stream id %1 failed").arg( nId ));
00885         return NULL;
00886     }
00887 
00888     DTC::LiveStreamInfo *hlsInfo = hls->GetLiveStreamInfo();
00889     if (!hlsInfo)
00890     {
00891         LOG( VB_UPNP, LOG_ERR,
00892              QString("HLS::GetLiveStreamInfo - for stream id %1 failed")
00893                      .arg( nId ));
00894         return NULL;
00895     }
00896 
00897     delete hls;
00898     return hlsInfo;
00899 }
00900 
00902 //
00904 
00905 DTC::LiveStreamInfoList *Content::GetLiveStreamList( void )
00906 {
00907     return HTTPLiveStream::GetLiveStreamInfoList();
00908 }
00909 
00911 //
00913 
00914 DTC::LiveStreamInfoList *Content::GetFilteredLiveStreamList( const QString   &FileName )
00915 {
00916     return HTTPLiveStream::GetLiveStreamInfoList(FileName);
00917 }
00918 
00920 //
00922 
00923 DTC::LiveStreamInfo *Content::AddRecordingLiveStream( int              nChanId,
00924                                                       const QDateTime &dtStartTime,
00925                                                       int              nMaxSegments,
00926                                                       int              nWidth,
00927                                                       int              nHeight,
00928                                                       int              nBitrate,
00929                                                       int              nAudioBitrate,
00930                                                       int              nSampleRate )
00931 {
00932     if (!dtStartTime.isValid())
00933         throw( "StartTime is invalid" );
00934 
00935     // ------------------------------------------------------------------
00936     // Read Recording From Database
00937     // ------------------------------------------------------------------
00938 
00939     ProgramInfo pginfo( (uint)nChanId, dtStartTime );
00940 
00941     if (!pginfo.GetChanID())
00942     {
00943         LOG( VB_UPNP, LOG_ERR, QString("AddRecordingLiveStream - for %1, %2 failed")
00944                                     .arg( nChanId )
00945                                     .arg( dtStartTime.toString() ));
00946         return NULL;
00947     }
00948 
00949     if ( pginfo.GetHostname().toLower() != gCoreContext->GetHostName().toLower())
00950     {
00951         // We only handle requests for local resources
00952 
00953         QString sMsg =
00954             QString("GetRecording: Wrong Host '%1' request from '%2'.")
00955                           .arg( gCoreContext->GetHostName())
00956                           .arg( pginfo.GetHostname() );
00957 
00958         LOG(VB_UPNP, LOG_ERR, sMsg);
00959 
00960         throw HttpRedirectException( pginfo.GetHostname() );
00961     }
00962 
00963     QString sFileName( GetPlaybackURL(&pginfo) );
00964 
00965     // ----------------------------------------------------------------------
00966     // check to see if the file exists
00967     // ----------------------------------------------------------------------
00968 
00969     if (!QFile::exists( sFileName ))
00970     {
00971         LOG( VB_UPNP, LOG_ERR, QString("AddRecordingLiveStream - for %1, %2 failed")
00972                                     .arg( nChanId )
00973                                     .arg( dtStartTime.toString() ));
00974         return NULL;
00975     }
00976 
00977     QFileInfo fInfo( sFileName );
00978 
00979     return AddLiveStream( pginfo.GetStorageGroup(), fInfo.fileName(),
00980                           pginfo.GetHostname(), nMaxSegments, nWidth,
00981                           nHeight, nBitrate, nAudioBitrate, nSampleRate );
00982 }
00983 
00985 //
00987 
00988 DTC::LiveStreamInfo *Content::AddVideoLiveStream( int nId,
00989                                                   int nMaxSegments,
00990                                                   int nWidth,
00991                                                   int nHeight,
00992                                                   int nBitrate,
00993                                                   int nAudioBitrate,
00994                                                   int nSampleRate )
00995 {
00996     if (nId < 0)
00997         throw( "Id is invalid" );
00998 
00999     VideoMetadataListManager::VideoMetadataPtr metadata =
01000                           VideoMetadataListManager::loadOneFromDatabase(nId);
01001 
01002     if (!metadata)
01003     {
01004         LOG( VB_UPNP, LOG_ERR, QString("AddVideoLiveStream - no metadata for %1")
01005                                     .arg( nId ));
01006         return NULL;
01007     }
01008 
01009     if ( metadata->GetHost().toLower() != gCoreContext->GetHostName().toLower())
01010     {
01011         // We only handle requests for local resources
01012 
01013         QString sMsg =
01014             QString("AddVideoLiveStream: Wrong Host '%1' request from '%2'.")
01015                           .arg( gCoreContext->GetHostName())
01016                           .arg( metadata->GetHost() );
01017 
01018         LOG(VB_UPNP, LOG_ERR, sMsg);
01019 
01020         throw HttpRedirectException( metadata->GetHost() );
01021     }
01022 
01023     StorageGroup sg("Videos", metadata->GetHost());
01024     QString sFileName = sg.FindFile(metadata->GetFilename());
01025 
01026     // ----------------------------------------------------------------------
01027     // check to see if the file exists
01028     // ----------------------------------------------------------------------
01029 
01030     if (!QFile::exists( sFileName ))
01031     {
01032         LOG( VB_UPNP, LOG_ERR, QString("AddVideoLiveStream - file does not exist."));
01033         return NULL;
01034     }
01035 
01036     return AddLiveStream( "Videos", metadata->GetFilename(),
01037                           metadata->GetHost(), nMaxSegments, nWidth,
01038                           nHeight, nBitrate, nAudioBitrate, nSampleRate );
01039 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends