32 #include <QImageWriter>
68 const QString &sFileName )
70 QString sGroup = sStorageGroup;
74 LOG(VB_UPNP, LOG_WARNING,
75 "GetFile - StorageGroup missing... using 'Default'");
79 if (sFileName.isEmpty())
81 QString sMsg (
"GetFile - FileName missing." );
93 QString sFullFileName = storage.
FindFile( sFileName );
95 if (sFullFileName.isEmpty())
98 QString(
"GetFile - Unable to find %1.").arg(sFileName));
107 if (QFile::exists( sFullFileName ))
109 return QFileInfo( sFullFileName );
112 LOG(VB_UPNP, LOG_ERR,
113 QString(
"GetFile - File Does not exist %1.").arg(sFullFileName));
123 const QString &sFileName,
127 QString sGroup = sStorageGroup;
129 if (sGroup.isEmpty())
131 LOG(VB_UPNP, LOG_WARNING,
132 "GetImageFile - StorageGroup missing... using 'Default'");
136 if (sFileName.isEmpty())
138 QString sMsg (
"GetImageFile - FileName missing." );
150 QString sFullFileName = storage.
FindFile( sFileName );
152 if (sFullFileName.isEmpty())
154 LOG(VB_UPNP, LOG_WARNING,
155 QString(
"GetImageFile - Unable to find %1.").arg(sFileName));
164 if (!QFile::exists( sFullFileName ))
166 LOG(VB_UPNP, LOG_WARNING,
167 QString(
"GetImageFile - File Does not exist %1.").arg(sFullFileName));
174 if ((nWidth == 0) && (nHeight == 0))
175 return QFileInfo( sFullFileName );
180 QString sNewFileName = QString(
"%1.%2x%3.jpg" )
181 .arg( sFullFileName )
189 if (QFile::exists( sNewFileName ))
190 return QFileInfo( sNewFileName );
196 auto *pImage =
new QImage( sFullFileName );
198 if (!pImage || pImage->isNull())
201 float fAspect = (float)(pImage->width()) / pImage->height();
204 nWidth = (int)rint(nHeight * fAspect);
207 nHeight = (int)rint(nWidth / fAspect);
209 QImage img = pImage->scaled( nWidth, nHeight, Qt::KeepAspectRatio,
210 Qt::SmoothTransformation);
212 QByteArray fname = sNewFileName.toLatin1();
213 img.save( fname.constData(),
"JPG", 60 );
217 return QFileInfo( sNewFileName );
227 if (sStorageGroup.isEmpty())
229 QString sMsg(
"GetDirList - StorageGroup missing.");
230 LOG(VB_UPNP, LOG_ERR, sMsg);
247 if (sStorageGroup.isEmpty())
249 QString sMsg(
"GetFileList - StorageGroup missing.");
250 LOG(VB_UPNP, LOG_ERR, sMsg);
265 const QString &sInetref,
278 if (sType.toLower() ==
"coverart")
283 else if (sType.toLower() ==
"fanart")
288 else if (sType.toLower() ==
"banner")
294 if (!map.contains(
type))
297 QUrl url(map.value(
type).url);
298 QString sFileName = url.path();
300 if (sFileName.isEmpty())
303 return GetImageFile( sgroup, sFileName, nWidth, nHeight);
312 const QDateTime &recstarttsRaw)
314 if ((RecordedId <= 0) &&
315 (chanid <= 0 || !recstarttsRaw.isValid()))
316 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
323 pginfo =
ProgramInfo(chanid, recstarttsRaw.toUTC());
343 int nId,
int nWidth,
int nHeight )
345 LOG(VB_UPNP, LOG_INFO, QString(
"GetVideoArtwork ID = %1").arg(nId));
347 QString sgroup =
"Coverart";
348 QString column =
"coverfile";
350 if (sType.toLower() ==
"coverart")
353 column =
"coverfile";
355 else if (sType.toLower() ==
"fanart")
360 else if (sType.toLower() ==
"banner")
365 else if (sType.toLower() ==
"screenshot")
367 sgroup =
"Screenshots";
368 column =
"screenshot";
377 QString querystr = QString(
"SELECT %1 FROM videometadata WHERE "
378 "intid = :ITEMID").arg(column);
389 QString sFileName = query.
value(0).toString();
391 if (sFileName.isEmpty())
394 return GetImageFile( sgroup, sFileName, nWidth, nHeight );
413 LOG(VB_GENERAL, LOG_DEBUG, QString(
"GetAlbumArt: %1").arg(sFullFileName));
420 QString sNewFileName = QString(
"/tmp/%1.%2x%3.jpg" )
421 .arg( QFileInfo(sFullFileName).fileName() )
429 if (QFile::exists( sNewFileName ))
430 return QFileInfo( sNewFileName );
438 if (sFullFileName.startsWith(
"myth://"))
440 RemoteFile rf(sFullFileName,
false,
false, 0s);
444 img.loadFromData(data);
447 img.load(sFullFileName);
454 if ((nWidth == 0) && (nHeight == 0))
456 if (!sFullFileName.startsWith(
"myth://"))
458 QFileInfo fi(sFullFileName);
459 if (fi.suffix().toLower() ==
"jpg")
463 else if (nWidth > img.width() && nHeight > img.height())
473 float fAspect = (float)(img.width()) / img.height();
475 if ( nWidth == 0 || nWidth > img.width() )
476 nWidth = (
int)rint(nHeight * fAspect);
478 if ( nHeight == 0 || nHeight > img.height() )
479 nHeight = (int)rint(nWidth / fAspect);
481 img = img.scaled( nWidth, nHeight, Qt::KeepAspectRatio,
482 Qt::SmoothTransformation);
485 QString fname = sNewFileName.toLatin1().constData();
488 if (!img.save( fname,
"JPG" ))
491 return QFileInfo( sNewFileName );
500 const QDateTime &recstarttsRaw,
504 const QString &sFormat )
506 if ((nRecordedId <= 0) &&
507 (nChanId <= 0 || !recstarttsRaw.isValid()))
508 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
510 if (!sFormat.isEmpty()
511 && !QImageWriter::supportedImageFormats().contains(sFormat.toLower().toLocal8Bit()))
513 throw QString(
"GetPreviewImage: Specified 'Format' is not supported.");
525 pginfo =
ProgramInfo(nChanId, recstarttsRaw.toUTC());
529 LOG(VB_GENERAL, LOG_ERR,
530 QString(
"GetPreviewImage: No recording for '%1'")
539 QString(
"GetPreviewImage: Wrong Host '%1' request from '%2'")
543 LOG(VB_UPNP, LOG_ERR, sMsg);
548 QString sImageFormat = sFormat;
549 if (sImageFormat.isEmpty())
550 sImageFormat =
"PNG";
558 QString sPreviewFileName;
560 auto nSecs = std::chrono::seconds(nSecsIn);
564 sPreviewFileName = QString(
"%1.png").arg(sFileName);
568 sPreviewFileName = QString(
"%1.%2.png").arg(sFileName).arg(nSecsIn);
571 if (!QFile::exists( sPreviewFileName ))
576 if (!pginfo.
IsLocal() && sFileName.startsWith(
"/"))
584 previewgen->SetPreviewTimeAsSeconds( nSecs );
585 previewgen->SetOutputFilename ( sPreviewFileName );
587 bool ok = previewgen->Run();
589 previewgen->deleteLater();
595 bool bDefaultPixmap = (nWidth == 0) && (nHeight == 0);
597 QString sNewFileName;
600 sNewFileName = sPreviewFileName;
603 sNewFileName = QString(
"%1.%2.%3x%4.%5" )
606 .arg( nWidth == 0 ? -1 : nWidth )
607 .arg( nHeight == 0 ? -1 : nHeight )
608 .arg( sImageFormat.toLower() );
614 if (QFile::exists( sNewFileName ))
616 if (QFileInfo(sPreviewFileName).lastModified() <=
617 QFileInfo(sNewFileName).lastModified())
618 return QFileInfo( sNewFileName );
621 QImage image = QImage(sPreviewFileName);
629 image = image.scaledToHeight(nHeight, Qt::SmoothTransformation);
630 else if ( nHeight <= 0 )
631 image = image.scaledToWidth(nWidth, Qt::SmoothTransformation);
633 image = image.scaled(nWidth, nHeight, Qt::IgnoreAspectRatio,
634 Qt::SmoothTransformation);
636 image.save(sNewFileName, sImageFormat.toUpper().toLocal8Bit());
642 LOG(VB_GENERAL, LOG_ERR,
"Unable to change permissions on "
643 "preview image. Backends and frontends "
644 "running under different users will be "
645 "unable to access it");
649 if (QFile::exists( sNewFileName ))
650 return QFileInfo( sNewFileName );
654 previewgen->SetPreviewTimeAsSeconds( nSecs );
655 previewgen->SetOutputFilename ( sNewFileName );
656 previewgen->SetOutputSize (QSize(nWidth,nHeight));
658 bool ok = previewgen->Run();
660 previewgen->deleteLater();
665 return QFileInfo( sNewFileName );
674 const QDateTime &recstarttsRaw )
676 if ((nRecordedId <= 0) &&
677 (nChanId <= 0 || !recstarttsRaw.isValid()))
678 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
689 pginfo =
ProgramInfo(nChanId, recstarttsRaw.toUTC());
693 LOG(VB_UPNP, LOG_ERR, QString(
"GetRecording - for '%1' failed")
705 QString(
"GetRecording: Wrong Host '%1' request from '%2'.")
709 LOG(VB_UPNP, LOG_ERR, sMsg);
720 if (QFile::exists( sFileName ))
721 return QFileInfo( sFileName );
742 query.
prepare(
"SELECT CONCAT_WS('/', music_directories.path, "
743 "music_songs.filename) AS filename FROM music_songs "
744 "LEFT JOIN music_directories ON "
745 "music_songs.directory_id="
746 "music_directories.directory_id "
747 "WHERE music_songs.song_id = :KEY");
759 sFileName = query.
value(0).toString();
763 if (sFileName.isEmpty())
766 return GetFile(
"Music", sFileName );
785 query.
prepare(
"SELECT filename FROM videometadata WHERE intid = :KEY" );
795 sFileName = query.
value(0).toString();
798 if (sFileName.isEmpty())
801 if (!QFile::exists( sFileName ))
802 return GetFile(
"Videos", sFileName );
804 return QFileInfo( sFileName );
812 const QString &sFileName )
814 if ((sFileName.isEmpty()) ||
815 (sFileName.contains(
"/../")) ||
816 (sFileName.startsWith(
"../")))
818 LOG(VB_GENERAL, LOG_ERR,
819 QString(
"ERROR checking for file, filename '%1' "
820 "fails sanity checks").arg(sFileName));
824 QString storageGroup =
"Default";
826 if (!sStorageGroup.isEmpty())
827 storageGroup = sStorageGroup;
831 QString fullname = sgroup.
FindFile(sFileName);
846 QFileInfo finfo(sURL);
847 QString
filename = finfo.fileName();
852 if (outDir.isEmpty())
854 LOG(VB_GENERAL, LOG_ERR,
855 QString(
"Unable to determine directory "
856 "to write to in %1 write command").arg(sURL));
863 LOG(VB_GENERAL, LOG_ERR,
864 QString(
"ERROR: %1 write filename '%2' does not "
865 "pass sanity checks.").arg(sURL,
filename));
879 const QString &sFileName,
880 const QString &sHostName,
888 QString sGroup = sStorageGroup;
890 if (sGroup.isEmpty())
892 LOG(VB_UPNP, LOG_WARNING,
893 "AddLiveStream - StorageGroup missing... using 'Default'");
897 if (sFileName.isEmpty())
899 QString sMsg (
"AddLiveStream - FileName missing." );
901 LOG(VB_UPNP, LOG_ERR, sMsg);
910 QString sFullFileName;
914 sFullFileName = storage.
FindFile( sFileName );
916 if (sFullFileName.isEmpty())
918 LOG(VB_UPNP, LOG_ERR,
919 QString(
"AddLiveStream - Unable to find %1.").arg(sFileName));
930 auto *hls =
new HTTPLiveStream(sFullFileName, nWidth, nHeight, nBitrate,
931 nAudioBitrate, nMaxSegments, 0, 0, nSampleRate);
935 LOG(VB_UPNP, LOG_ERR,
936 "AddLiveStream - Unable to create HTTPLiveStream.");
975 LOG( VB_UPNP, LOG_ERR,
976 QString(
"GetLiveStream - for stream id %1 failed").arg( nId ));
983 LOG( VB_UPNP, LOG_ERR,
984 QString(
"HLS::GetLiveStreamInfo - for stream id %1 failed")
1009 const QDateTime &recstarttsRaw,
1017 if ((nRecordedId <= 0) &&
1018 (nChanId <= 0 || !recstarttsRaw.isValid()))
1019 throw QString(
"Recorded ID or Channel ID and StartTime appears invalid.");
1027 if (nRecordedId > 0)
1030 pginfo =
ProgramInfo(nChanId, recstarttsRaw.toUTC());
1034 LOG(VB_UPNP, LOG_ERR,
1035 QString(
"AddRecordingLiveStream - for %1, %2 failed")
1036 .arg(QString::number(nRecordedId)));
1043 && ! masterBackendOverride)
1048 QString(
"GetRecording: Wrong Host '%1' request from '%2'.")
1052 LOG(VB_UPNP, LOG_ERR, sMsg);
1063 if (!QFile::exists( sFileName ))
1065 LOG( VB_UPNP, LOG_ERR, QString(
"AddRecordingLiveStream - for %1, %2 failed")
1067 .arg( recstarttsRaw.toUTC().toString() ));
1071 QFileInfo fInfo( sFileName );
1074 if (masterBackendOverride)
1080 hostName, nMaxSegments, nWidth,
1081 nHeight, nBitrate, nAudioBitrate, nSampleRate );
1097 throw QString(
"Id is invalid" );
1104 LOG( VB_UPNP, LOG_ERR, QString(
"AddVideoLiveStream - no metadata for %1")
1114 QString(
"AddVideoLiveStream: Wrong Host '%1' request from '%2'.")
1116 metadata->GetHost() );
1118 LOG(VB_UPNP, LOG_ERR, sMsg);
1124 QString sFileName = sg.
FindFile(metadata->GetFilename());
1130 if (!QFile::exists( sFileName ))
1132 LOG( VB_UPNP, LOG_ERR, QString(
"AddVideoLiveStream - file does not exist."));
1137 metadata->GetHost(), nMaxSegments, nWidth,
1138 nHeight, nBitrate, nAudioBitrate, nSampleRate );