MythTV  master
video.cpp
Go to the documentation of this file.
1 // Program Name: video.cpp
3 // Created : Apr. 21, 2011
4 //
5 // Copyright (c) 2011 Robert McNamara <rmcnamara@mythtv.org>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //
25 
26 // C++
27 #include <cmath>
28 
29 // Qt
30 #include <QList>
31 #include <QFile>
32 #include <QMutex>
33 
34 // MythTV
35 #include "libmythbase/compat.h"
37 #include "libmythbase/mythdate.h"
39 #include "libmythbase/mythversion.h"
40 #include "libmythbase/remotefile.h"
46 #include "libmythtv/mythavutil.h"
47 
48 // MythBackend
49 #include "serviceUtil.h"
50 #include "video.h"
51 
53 //
55 
57  const QString &Sort,
58  bool bDescending,
59  int nStartIndex,
60  int nCount )
61 {
62  QString fields = "title,director,studio,plot,rating,year,releasedate,"
63  "userrating,length,playcount,filename,hash,showlevel,"
64  "coverfile,inetref,collectionref,homepage,childid,browse,watched,"
65  "playcommand,category,intid,trailer,screenshot,banner,fanart,"
66  "subtitle,tagline,season,episode,host,insertdate,processed,contenttype";
67 
68  QStringList sortFields = fields.split(',');
69 
71 
72  QString sql = "";
73  if (!Folder.isEmpty())
74  sql.append(" WHERE filename LIKE '" + Folder + "%'");
75 
76  sql.append(" ORDER BY ");
77  QString sort = Sort.toLower();
78  if (sort == "added")
79  sql.append("insertdate");
80  else if (sort == "released")
81  sql.append("releasedate");
82  else if (sortFields.contains(sort))
83  sql.append(sort);
84  else
85  sql.append("intid");
86 
87  if (bDescending)
88  sql += " DESC";
90 
91  std::vector<VideoMetadataListManager::VideoMetadataPtr> videos(videolist.begin(), videolist.end());
92 
93  // ----------------------------------------------------------------------
94  // Build Response
95  // ----------------------------------------------------------------------
96 
97  auto *pVideoMetadataInfos = new DTC::VideoMetadataInfoList();
98 
99  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)videos.size() ) : 0;
100  nCount = (nCount > 0) ? std::min( nCount, (int)videos.size() ) : videos.size();
101  int nEndIndex = std::min((nStartIndex + nCount), (int)videos.size() );
102 
103  for( int n = nStartIndex; n < nEndIndex; n++ )
104  {
105  DTC::VideoMetadataInfo *pVideoMetadataInfo = pVideoMetadataInfos->AddNewVideoMetadataInfo();
106 
107  VideoMetadataListManager::VideoMetadataPtr metadata = videos[n];
108 
109  if (metadata)
110  FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
111  }
112 
113  int curPage = 0;
114  int totalPages = 0;
115  if (nCount == 0)
116  totalPages = 1;
117  else
118  totalPages = (int)ceil((float)videos.size() / nCount);
119 
120  if (totalPages == 1)
121  curPage = 1;
122  else
123  {
124  curPage = (int)ceil((float)nStartIndex / nCount) + 1;
125  }
126 
127  pVideoMetadataInfos->setStartIndex ( nStartIndex );
128  pVideoMetadataInfos->setCount ( nCount );
129  pVideoMetadataInfos->setCurrentPage ( curPage );
130  pVideoMetadataInfos->setTotalPages ( totalPages );
131  pVideoMetadataInfos->setTotalAvailable( videos.size() );
132  pVideoMetadataInfos->setAsOf ( MythDate::current() );
133  pVideoMetadataInfos->setVersion ( MYTH_BINARY_VERSION );
134  pVideoMetadataInfos->setProtoVer ( MYTH_PROTO_VERSION );
135 
136  return pVideoMetadataInfos;
137 }
138 
140 //
142 
144 {
147 
148  if ( !metadata )
149  throw( QString( "No metadata found for selected ID!." ));
150 
151  auto *pVideoMetadataInfo = new DTC::VideoMetadataInfo();
152 
153  FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
154 
155  return pVideoMetadataInfo;
156 }
157 
159 //
161 
163 {
166  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
167  mlm->setList(videolist);
168  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byFilename(FileName);
169 
170  if ( !metadata )
171  throw( QString( "No metadata found for selected filename!." ));
172 
173  auto *pVideoMetadataInfo = new DTC::VideoMetadataInfo();
174 
175  FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
176 
177  return pVideoMetadataInfo;
178 }
179 
181 //
183 
185  const QString &Subtitle,
186  const QString &Inetref,
187  int Season,
188  int Episode,
189  const QString &GrabberType,
190  bool AllowGeneric )
191 {
192  auto *pVideoLookups = new DTC::VideoLookupList();
193 
194  MetadataLookupList list;
195 
196  auto *factory = new MetadataFactory(nullptr);
197 
198  if (factory)
199  {
200  list = factory->SynchronousLookup(Title, Subtitle,
201  Inetref, Season, Episode,
202  GrabberType, AllowGeneric);
203  }
204 
205  if ( list.empty() )
206  return pVideoLookups;
207 
208  //MetadataLookupList is a reference counted list.
209  //it will delete all its content at its end of life
210  for(const auto & lookup : std::as_const(list))
211  {
212  DTC::VideoLookup *pVideoLookup = pVideoLookups->AddNewVideoLookup();
213 
214  if (lookup)
215  {
216  pVideoLookup->setTitle(lookup->GetTitle());
217  pVideoLookup->setSubTitle(lookup->GetSubtitle());
218  pVideoLookup->setSeason(lookup->GetSeason());
219  pVideoLookup->setEpisode(lookup->GetEpisode());
220  pVideoLookup->setYear(lookup->GetYear());
221  pVideoLookup->setTagline(lookup->GetTagline());
222  pVideoLookup->setDescription(lookup->GetDescription());
223  pVideoLookup->setCertification(lookup->GetCertification());
224  pVideoLookup->setInetref(lookup->GetInetref());
225  pVideoLookup->setCollectionref(lookup->GetCollectionref());
226  pVideoLookup->setHomePage(lookup->GetHomepage());
227  pVideoLookup->setReleaseDate(
228  QDateTime(lookup->GetReleaseDate(),
229  QTime(0,0),Qt::LocalTime).toUTC());
230  pVideoLookup->setUserRating(lookup->GetUserRating());
231  pVideoLookup->setLength(lookup->GetRuntime().count());
232  pVideoLookup->setLanguage(lookup->GetLanguage());
233  pVideoLookup->setCountries(lookup->GetCountries());
234  pVideoLookup->setPopularity(lookup->GetPopularity());
235  pVideoLookup->setBudget(lookup->GetBudget());
236  pVideoLookup->setRevenue(lookup->GetRevenue());
237  pVideoLookup->setIMDB(lookup->GetIMDB());
238  pVideoLookup->setTMSRef(lookup->GetTMSref());
239 
240  ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
241  ArtworkList::iterator c;
242  for (c = coverartlist.begin(); c != coverartlist.end(); ++c)
243  {
244  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
245  art->setType("coverart");
246  art->setUrl((*c).url);
247  art->setThumbnail((*c).thumbnail);
248  art->setWidth((*c).width);
249  art->setHeight((*c).height);
250  }
251  ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
252  ArtworkList::iterator f;
253  for (f = fanartlist.begin(); f != fanartlist.end(); ++f)
254  {
255  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
256  art->setType("fanart");
257  art->setUrl((*f).url);
258  art->setThumbnail((*f).thumbnail);
259  art->setWidth((*f).width);
260  art->setHeight((*f).height);
261  }
262  ArtworkList bannerlist = lookup->GetArtwork(kArtworkBanner);
263  ArtworkList::iterator b;
264  for (b = bannerlist.begin(); b != bannerlist.end(); ++b)
265  {
266  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
267  art->setType("banner");
268  art->setUrl((*b).url);
269  art->setThumbnail((*b).thumbnail);
270  art->setWidth((*b).width);
271  art->setHeight((*b).height);
272  }
273  ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
274  ArtworkList::iterator s;
275  for (s = screenshotlist.begin(); s != screenshotlist.end(); ++s)
276  {
277  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
278  art->setType("screenshot");
279  art->setUrl((*s).url);
280  art->setThumbnail((*s).thumbnail);
281  art->setWidth((*s).width);
282  art->setHeight((*s).height);
283  }
284  }
285  }
286 
287  pVideoLookups->setCount ( list.count() );
288  pVideoLookups->setAsOf ( MythDate::current() );
289  pVideoLookups->setVersion ( MYTH_BINARY_VERSION );
290  pVideoLookups->setProtoVer ( MYTH_PROTO_VERSION );
291 
292  delete factory;
293 
294  return pVideoLookups;
295 }
296 
298 //
300 
302 {
303  bool bResult = false;
304 
307  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
308  mlm->setList(videolist);
309  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byID(Id);
310 
311  if (metadata)
312  bResult = metadata->DeleteFromDatabase();
313 
314  return bResult;
315 }
316 
318 //
320 
321 bool Video::AddVideo( const QString &sFileName,
322  const QString &sHostName )
323 {
324  if ( sHostName.isEmpty() )
325  throw( QString( "Host not provided! Local storage is deprecated and "
326  "is not supported by the API." ));
327 
328  if ( sFileName.isEmpty() ||
329  (sFileName.contains("/../")) ||
330  (sFileName.startsWith("../")) )
331  {
332  throw( QString( "Filename not provided, or fails sanity checks!" ));
333  }
334 
335  StorageGroup sgroup("Videos", sHostName);
336 
337  QString fullname = sgroup.FindFile(sFileName);
338 
339  if ( !QFile::exists(fullname) )
340  throw( QString( "Provided filename does not exist!" ));
341 
342  QString hash = FileHash(fullname);
343 
344  if (hash == "NULL")
345  {
346  LOG(VB_GENERAL, LOG_ERR, "Video Hash Failed. Unless this is a DVD or "
347  "Blu-ray, something has probably gone wrong.");
348  hash = "";
349  }
350 
351  VideoMetadata newFile(sFileName, QString(), hash,
357  QString(), QString(), QString(), QString(),
358  QString(), VIDEO_YEAR_DEFAULT,
359  QDate::fromString("0000-00-00","YYYY-MM-DD"),
360  VIDEO_INETREF_DEFAULT, 0, QString(),
362  0.0, VIDEO_RATING_DEFAULT, 0, 0,
363  0, 0,
364  MythDate::current().date(), 0,
366 
367  newFile.SetHost(sHostName);
368  newFile.SaveToDatabase();
369 
370  return true;
371 }
372 
374 //
376 
378  bool bWatched )
379 {
382  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
383  mlm->setList(videolist);
384  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byID(nId);
385 
386  if ( !metadata )
387  return false;
388 
389  metadata->SetWatched(bWatched);
390  metadata->UpdateDatabase();
391 
392  return true;
393 }
394 
396 //
398 
399 DTC::BlurayInfo* Video::GetBluray( const QString &sPath )
400 {
401  QString path = sPath;
402 
403  if (sPath.isEmpty())
404  path = gCoreContext->GetSetting( "BluRayMountpoint", "/media/cdrom");
405 
406  LOG(VB_GENERAL, LOG_NOTICE,
407  QString("Parsing Blu-ray at path: %1 ").arg(path));
408 
409  auto *bdmeta = new BlurayMetadata(path);
410 
411  if ( !bdmeta )
412  throw( QString( "Unable to open Blu-ray Metadata Parser!" ));
413 
414  if ( !bdmeta->OpenDisc() )
415  throw( QString( "Unable to open Blu-ray Disc/Path!" ));
416 
417  if ( !bdmeta->ParseDisc() )
418  throw( QString( "Unable to parse metadata from Blu-ray Disc/Path!" ));
419 
420  auto *pBlurayInfo = new DTC::BlurayInfo();
421 
422  pBlurayInfo->setPath(path);
423  pBlurayInfo->setTitle(bdmeta->GetTitle());
424  pBlurayInfo->setAltTitle(bdmeta->GetAlternateTitle());
425  pBlurayInfo->setDiscLang(bdmeta->GetDiscLanguage());
426  pBlurayInfo->setDiscNum(bdmeta->GetCurrentDiscNumber());
427  pBlurayInfo->setTotalDiscNum(bdmeta->GetTotalDiscNumber());
428  pBlurayInfo->setTitleCount(bdmeta->GetTitleCount());
429  pBlurayInfo->setThumbCount(bdmeta->GetThumbnailCount());
430  pBlurayInfo->setTopMenuSupported(bdmeta->GetTopMenuSupported());
431  pBlurayInfo->setFirstPlaySupported(bdmeta->GetFirstPlaySupported());
432  pBlurayInfo->setNumHDMVTitles(bdmeta->GetNumHDMVTitles());
433  pBlurayInfo->setNumBDJTitles(bdmeta->GetNumBDJTitles());
434  pBlurayInfo->setNumUnsupportedTitles(bdmeta->GetNumUnsupportedTitles());
435  pBlurayInfo->setAACSDetected(bdmeta->GetAACSDetected());
436  pBlurayInfo->setLibAACSDetected(bdmeta->GetLibAACSDetected());
437  pBlurayInfo->setAACSHandled(bdmeta->GetAACSHandled());
438  pBlurayInfo->setBDPlusDetected(bdmeta->GetBDPlusDetected());
439  pBlurayInfo->setLibBDPlusDetected(bdmeta->GetLibBDPlusDetected());
440  pBlurayInfo->setBDPlusHandled(bdmeta->GetBDPlusHandled());
441 
442  QStringList thumbs = bdmeta->GetThumbnails();
443  if (!thumbs.empty())
444  pBlurayInfo->setThumbPath(thumbs.at(0));
445 
446  delete bdmeta;
447 
448  return pBlurayInfo;
449 }
450 
452 //
454 
456  const QString &sTitle,
457  const QString &sSubTitle,
458  const QString &sTagLine,
459  const QString &sDirector,
460  const QString &sStudio,
461  const QString &sPlot,
462  const QString &sRating,
463  const QString &sInetref,
464  int nCollectionRef,
465  const QString &sHomePage,
466  int nYear,
467  const QDate &sReleasedate,
468  float fUserRating,
469  int nLength,
470  int nPlayCount,
471  int nSeason,
472  int nEpisode,
473  int nShowLevel,
474  const QString &sFileName,
475  const QString &sHash,
476  const QString &sCoverFile,
477  int nChildID,
478  bool bBrowse,
479  bool bWatched,
480  bool bProcessed,
481  const QString &sPlayCommand,
482  int nCategory,
483  const QString &sTrailer,
484  const QString &sHost,
485  const QString &sScreenshot,
486  const QString &sBanner,
487  const QString &sFanart,
488  const QDate &sInsertDate,
489  const QString &sContentType,
490  const QString &sGenres,
491  const QString &sCast,
492  const QString &sCountries)
493 {
494  bool update_required = false;
497  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
498  mlm->setList(videolist);
499  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byID(nId);
500 
501  if (!metadata)
502  {
503  LOG(VB_GENERAL, LOG_ERR, QString("UpdateVideoMetadata: Id=%1 not found")
504  .arg(nId));
505  return false;
506  }
507 
508  if (m_parsedParams.contains("title"))
509  {
510  metadata->SetTitle(sTitle);
511  update_required = true;
512  }
513 
514  if (m_parsedParams.contains("subtitle"))
515  {
516  metadata->SetSubtitle(sSubTitle);
517  update_required = true;
518  }
519 
520  if (m_parsedParams.contains("tagline"))
521  {
522  metadata->SetTagline(sTagLine);
523  update_required = true;
524  }
525 
526  if (m_parsedParams.contains("director"))
527  {
528  metadata->SetDirector(sDirector);
529  update_required = true;
530  }
531 
532  if (m_parsedParams.contains("studio"))
533  {
534  metadata->SetStudio(sStudio);
535  update_required = true;
536  }
537 
538  if (m_parsedParams.contains("plot"))
539  {
540  metadata->SetPlot(sPlot);
541  update_required = true;
542  }
543 
544  if (m_parsedParams.contains("userrating"))
545  {
546  metadata->SetUserRating(fUserRating);
547  update_required = true;
548  }
549 
550  if (m_parsedParams.contains("inetref"))
551  {
552  metadata->SetInetRef(sInetref);
553  update_required = true;
554  }
555 
556  if (m_parsedParams.contains("collectionref"))
557  {
558  metadata->SetCollectionRef(nCollectionRef);
559  update_required = true;
560  }
561 
562  if (m_parsedParams.contains("homepage"))
563  {
564  metadata->SetHomepage(sHomePage);
565  update_required = true;
566  }
567 
568  if (m_parsedParams.contains("year"))
569  {
570  metadata->SetYear(nYear);
571  update_required = true;
572  }
573 
574  if (m_parsedParams.contains("releasedate"))
575  {
576  metadata->SetReleaseDate(sReleasedate);
577  update_required = true;
578  }
579 
580  if (m_parsedParams.contains("rating"))
581  {
582  metadata->SetRating(sRating);
583  update_required = true;
584  }
585 
586  if (m_parsedParams.contains("length"))
587  {
588  metadata->SetLength(std::chrono::minutes(nLength));
589  update_required = true;
590  }
591 
592  if (m_parsedParams.contains("playcount"))
593  {
594  metadata->SetPlayCount(nPlayCount);
595  update_required = true;
596  }
597 
598  if (m_parsedParams.contains("season"))
599  {
600  metadata->SetSeason(nSeason);
601  update_required = true;
602  }
603 
604  if (m_parsedParams.contains("episode"))
605  {
606  metadata->SetEpisode(nEpisode);
607  update_required = true;
608  }
609 
610  if (m_parsedParams.contains("showlevel"))
611  {
612  metadata->SetShowLevel(ParentalLevel::Level(nShowLevel));
613  update_required = true;
614  }
615 
616  if (m_parsedParams.contains("filename"))
617  {
618  metadata->SetFilename(sFileName);
619  update_required = true;
620  }
621 
622  if (m_parsedParams.contains("hash"))
623  {
624  metadata->SetHash(sHash);
625  update_required = true;
626  }
627 
628  if (m_parsedParams.contains("coverfile"))
629  {
630  metadata->SetCoverFile(sCoverFile);
631  update_required = true;
632  }
633 
634  if (m_parsedParams.contains("childid"))
635  {
636  metadata->SetChildID(nChildID);
637  update_required = true;
638  }
639 
640  if (m_parsedParams.contains("browse"))
641  {
642  metadata->SetBrowse(bBrowse);
643  update_required = true;
644  }
645 
646  if (m_parsedParams.contains("watched"))
647  {
648  metadata->SetWatched(bWatched);
649  update_required = true;
650  }
651 
652  if (m_parsedParams.contains("processed"))
653  {
654  metadata->SetProcessed(bProcessed);
655  update_required = true;
656  }
657 
658  if (m_parsedParams.contains("playcommand"))
659  {
660  metadata->SetPlayCommand(sPlayCommand);
661  update_required = true;
662  }
663 
664  if (m_parsedParams.contains("category"))
665  {
666  metadata->SetCategoryID(nCategory);
667  update_required = true;
668  }
669 
670  if (m_parsedParams.contains("trailer"))
671  {
672  metadata->SetTrailer(sTrailer);
673  update_required = true;
674  }
675 
676  if (m_parsedParams.contains("host"))
677  {
678  metadata->SetHost(sHost);
679  update_required = true;
680  }
681 
682  if (m_parsedParams.contains("screenshot"))
683  {
684  metadata->SetScreenshot(sScreenshot);
685  update_required = true;
686  }
687 
688  if (m_parsedParams.contains("banner"))
689  {
690  metadata->SetBanner(sBanner);
691  update_required = true;
692  }
693 
694  if (m_parsedParams.contains("fanart"))
695  {
696  metadata->SetFanart(sFanart);
697  update_required = true;
698  }
699 
700  if (m_parsedParams.contains("insertdate"))
701  {
702  metadata->SetInsertdate(sInsertDate);
703  update_required = true;
704  }
705 
706  if (m_parsedParams.contains("contenttype"))
707  {
708  // valid values for ContentType are 'MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO'
709  VideoContentType contentType = kContentUnknown;
710  if (sContentType == "MOVIE")
711  contentType = kContentMovie;
712 
713  if (sContentType == "TELEVISION")
714  contentType = kContentTelevision;
715 
716  if (sContentType == "ADULT")
717  contentType = kContentAdult;
718 
719  if (sContentType == "MUSICVIDEO")
720  contentType = kContentMusicVideo;
721 
722  if (sContentType == "HOMEVIDEO")
723  contentType = kContentHomeMovie;
724 
725  if (contentType != kContentUnknown)
726  {
727  metadata->SetContentType(contentType);
728  update_required = true;
729  }
730  else
731  LOG(VB_GENERAL, LOG_ERR, QString("UpdateVideoMetadata: Ignoring unknown ContentType: %1").arg(sContentType));
732  }
733 
734  if (m_parsedParams.contains("genres"))
735  {
737  QStringList genresList = sGenres.split(',', Qt::SkipEmptyParts);
738  std::transform(genresList.cbegin(), genresList.cend(), std::back_inserter(genres),
739  [](const QString& name)
740  {return VideoMetadata::genre_list::value_type(-1, name.simplified());} );
741 
742  metadata->SetGenres(genres);
743  update_required = true;
744  }
745 
746  if (m_parsedParams.contains("cast"))
747  {
749  QStringList castList = sCast.split(',', Qt::SkipEmptyParts);
750  std::transform(castList.cbegin(), castList.cend(), std::back_inserter(cast),
751  [](const QString& name)
752  {return VideoMetadata::cast_list::value_type(-1, name.simplified());} );
753 
754  metadata->SetCast(cast);
755  update_required = true;
756  }
757 
758  if (m_parsedParams.contains("countries"))
759  {
760  VideoMetadata::country_list countries;
761  QStringList countryList = sCountries.split(',', Qt::SkipEmptyParts);
762  std::transform(countryList.cbegin(), countryList.cend(), std::back_inserter(countries),
763  [](const QString& name)
764  {return VideoMetadata::country_list::value_type(-1, name.simplified());} );
765 
766  metadata->SetCountries(countries);
767  update_required = true;
768  }
769 
770  if (update_required)
771  metadata->UpdateDatabase();
772 
773  return true;
774 }
775 
777 // Jun 3, 2020
778 // Service to get stream info for all streams in a media file.
779 // This gets some basic info. If anything more is needed it can be added,
780 // depending on whether it is available from ffmpeg avformat apis.
781 // See the MythStreamInfoList class for the code that uses avformat to
782 // extract the information.
784 
786  ( const QString &storageGroup,
787  const QString &FileName )
788 {
789 
790  // Search for the filename
791 
792  StorageGroup storage( storageGroup );
793  QString sFullFileName = storage.FindFile( FileName );
794  MythStreamInfoList infos(sFullFileName);
795 
796  // The constructor of this class reads the file and gets the needed
797  // information.
798  auto *pVideoStreamInfos = new DTC::VideoStreamInfoList();
799 
800  pVideoStreamInfos->setCount ( infos.m_streamInfoList.size() );
801  pVideoStreamInfos->setAsOf ( MythDate::current() );
802  pVideoStreamInfos->setVersion ( MYTH_BINARY_VERSION );
803  pVideoStreamInfos->setProtoVer ( MYTH_PROTO_VERSION );
804  pVideoStreamInfos->setErrorCode ( infos.m_errorCode );
805  pVideoStreamInfos->setErrorMsg ( infos.m_errorMsg );
806 
807  for (const auto & info : std::as_const(infos.m_streamInfoList))
808  {
809  DTC::VideoStreamInfo *pVideoStreamInfo = pVideoStreamInfos->AddNewVideoStreamInfo();
810  pVideoStreamInfo->setCodecType ( QString(QChar(info.m_codecType)) );
811  pVideoStreamInfo->setCodecName ( info.m_codecName );
812  pVideoStreamInfo->setWidth ( info.m_width );
813  pVideoStreamInfo->setHeight ( info.m_height );
814  pVideoStreamInfo->setAspectRatio ( info.m_SampleAspectRatio );
815  pVideoStreamInfo->setFieldOrder ( info.m_fieldOrder );
816  pVideoStreamInfo->setFrameRate ( info.m_frameRate );
817  pVideoStreamInfo->setAvgFrameRate ( info.m_avgFrameRate );
818  pVideoStreamInfo->setChannels ( info.m_channels );
819  pVideoStreamInfo->setDuration ( info.m_duration );
820 
821  }
822  return pVideoStreamInfos;
823 }
824 
826 // Get bookmark of a video as a frame number.
828 
830 {
831  MSqlQuery query(MSqlQuery::InitCon());
832 
833  query.prepare("SELECT filename "
834  "FROM videometadata "
835  "WHERE intid = :ID ");
836  query.bindValue(":ID", Id);
837 
838  if (!query.exec())
839  {
840  MythDB::DBError("Video::GetSavedBookmark", query);
841  return 0;
842  }
843 
844  QString fileName;
845 
846  if (query.next())
847  fileName = query.value(0).toString();
848  else
849  {
850  LOG(VB_GENERAL, LOG_ERR, QString("Video/GetSavedBookmark Video id %1 Not found.").arg(Id));
851  return -1;
852  }
853 
854  ProgramInfo pi(fileName,
855  nullptr, // _plot,
856  nullptr, // _title,
857  nullptr, // const QString &_sortTitle,
858  nullptr, // const QString &_subtitle,
859  nullptr, // const QString &_sortSubtitle,
860  nullptr, // const QString &_director,
861  0, // int _season,
862  0, // int _episode,
863  nullptr, // const QString &_inetref,
864  0min, // uint _length_in_minutes,
865  0, // uint _year,
866  nullptr); //const QString &_programid);
867 
868  long ret = pi.QueryBookmark();
869  return ret;
870 }
871 
873 // Set bookmark of a video as a frame number.
875 
876 bool Video::SetSavedBookmark( int Id, long Offset )
877 {
878  MSqlQuery query(MSqlQuery::InitCon());
879 
880  query.prepare("SELECT filename "
881  "FROM videometadata "
882  "WHERE intid = :ID ");
883  query.bindValue(":ID", Id);
884 
885  if (!query.exec())
886  {
887  MythDB::DBError("Video::SetSavedBookmark", query);
888  return false;
889  }
890 
891  QString fileName;
892 
893  if (query.next())
894  fileName = query.value(0).toString();
895  else
896  {
897  LOG(VB_GENERAL, LOG_ERR, QString("Video/SetSavedBookmark Video id %1 Not found.").arg(Id));
898  return false;
899  }
900 
901  ProgramInfo pi(fileName,
902  nullptr, // _plot,
903  nullptr, // _title,
904  nullptr, // const QString &_sortTitle,
905  nullptr, // const QString &_subtitle,
906  nullptr, // const QString &_sortSubtitle,
907  nullptr, // const QString &_director,
908  0, // int _season,
909  0, // int _episode,
910  nullptr, // const QString &_inetref,
911  0min, // uint _length_in_minutes,
912  0, // uint _year,
913  nullptr); //const QString &_programid);
914 
915  pi.SaveBookmark(Offset);
916  return true;
917 }
918 
920 //
serviceUtil.h
MythStreamInfoList::m_errorMsg
QString m_errorMsg
Definition: mythavutil.h:102
BlurayMetadata
Definition: bluraymetadata.h:25
DTC::VideoLookup::AddNewArtwork
ArtworkItem * AddNewArtwork()
Definition: videoLookupInfo.h:165
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:813
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
VideoMetadata
Definition: videometadata.h:24
GrabberType
GrabberType
Definition: metadatagrabber.h:20
FillVideoMetadataInfo
void FillVideoMetadataInfo(DTC::VideoMetadataInfo *pVideoMetadataInfo, const VideoMetadataListManager::VideoMetadataPtr &pMetadata, bool bDetails)
Definition: serviceUtil.cpp:414
Video::GetVideoList
DTC::VideoMetadataInfoList * GetVideoList(const QString &Folder, const QString &Sort, bool Descending, int StartIndex, int Count) override
Definition: video.cpp:56
ProgramInfo::SaveBookmark
void SaveBookmark(uint64_t frame)
Clears any existing bookmark in DB and if frame is greater than 0 sets a new bookmark.
Definition: programinfo.cpp:2669
ParentalLevel::plLowest
@ plLowest
Definition: parentalcontrols.h:12
videometadata.h
DTC::VideoLookup
Definition: videoLookupInfo.h:68
DTC::VideoStreamInfo
Definition: videoStreamInfo.h:25
VideoMetadataListManager
Definition: videometadatalistmanager.h:10
simple_ref_ptr
Definition: quicksp.h:24
ArtworkList
QList< ArtworkInfo > ArtworkList
Definition: metadataimagehelper.h:30
StorageGroup::FindFile
QString FindFile(const QString &filename)
Definition: storagegroup.cpp:597
Video::GetStreamInfo
DTC::VideoStreamInfoList * GetStreamInfo(const QString &StorageGroup, const QString &FileName) override
Definition: video.cpp:786
video.h
MythStreamInfoList
Definition: mythavutil.h:98
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
VideoMetadata::country_list
std::vector< country_entry > country_list
Definition: videometadata.h:33
DTC::VideoLookupList
Definition: videoLookupInfoList.h:24
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:619
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
VideoMetadata::genre_list
std::vector< genre_entry > genre_list
Definition: videometadata.h:32
DTC::VideoStreamInfoList
Definition: videoStreamInfoList.h:24
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
VideoMetadataListManager::loadAllFromDatabase
static void loadAllFromDatabase(metadata_list &items, const QString &sql="", const QString &bindValue="")
Load videometadata database into memory.
Definition: videometadatalistmanager.cpp:128
ProgramInfo::QueryBookmark
uint64_t QueryBookmark(void) const
Gets any bookmark position in database, unless the ignore bookmark flag is set.
Definition: programinfo.cpp:2793
MythStreamInfoList::m_errorCode
int m_errorCode
Definition: mythavutil.h:101
mythdate.h
DTC::BlurayInfo
Definition: blurayInfo.h:24
Video::LookupVideo
DTC::VideoLookupList * LookupVideo(const QString &Title, const QString &Subtitle, const QString &Inetref, int Season, int Episode, const QString &GrabberType, bool AllowGeneric) override
Definition: video.cpp:184
remotefile.h
ParentalLevel::Level
Level
Definition: parentalcontrols.h:12
globals.h
Video::GetVideo
DTC::VideoMetadataInfo * GetVideo(int Id) override
Definition: video.cpp:143
RefCountedList< MetadataLookup >
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:551
compat.h
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
VideoMetadata::SaveToDatabase
void SaveToDatabase()
Definition: videometadata.cpp:1947
VIDEO_COVERFILE_DEFAULT
const QString VIDEO_COVERFILE_DEFAULT
Definition: globals.cpp:25
VIDEO_PLOT_DEFAULT
const QString VIDEO_PLOT_DEFAULT
Definition: globals.cpp:32
kArtworkFanart
@ kArtworkFanart
Definition: metadataimagehelper.h:12
kContentTelevision
@ kContentTelevision
Definition: metadatacommon.h:62
Video::GetVideoByFileName
DTC::VideoMetadataInfo * GetVideoByFileName(const QString &FileName) override
Definition: video.cpp:162
DTC::ArtworkItem
Definition: videoLookupInfo.h:25
Service::m_parsedParams
QList< QString > m_parsedParams
Definition: service.h:68
storagegroup.h
VIDEO_TRAILER_DEFAULT
const QString VIDEO_TRAILER_DEFAULT
Definition: globals.cpp:26
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
Video::GetSavedBookmark
long GetSavedBookmark(int Id) override
Definition: video.cpp:829
VIDEO_INETREF_DEFAULT
const QString VIDEO_INETREF_DEFAULT
Definition: globals.cpp:24
VIDEO_FANART_DEFAULT
const QString VIDEO_FANART_DEFAULT
Definition: globals.cpp:29
MetadataFactory
Definition: metadatafactory.h:85
Video::UpdateVideoWatchedStatus
bool UpdateVideoWatchedStatus(int Id, bool Watched) override
Definition: video.cpp:377
Video::RemoveVideoFromDB
bool RemoveVideoFromDB(int Id) override
Definition: video.cpp:301
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
Video::AddVideo
bool AddVideo(const QString &FileName, const QString &HostName) override
Definition: video.cpp:321
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
VideoContentType
VideoContentType
Definition: metadatacommon.h:60
mythmiscutil.h
mythcorecontext.h
VideoMetadata::cast_list
std::vector< cast_entry > cast_list
Definition: videometadata.h:34
VideoMetadata::SetHost
void SetHost(const QString &host)
Definition: videometadata.cpp:1837
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:889
VIDEO_RATING_DEFAULT
const QString VIDEO_RATING_DEFAULT
Definition: globals.cpp:30
VideoMetadataListManager::loadOneFromDatabase
static VideoMetadataPtr loadOneFromDatabase(uint id)
Definition: videometadatalistmanager.cpp:111
bluraymetadata.h
Video::SetSavedBookmark
bool SetSavedBookmark(int Id, long Offset) override
Definition: video.cpp:876
mythavutil.h
DTC::VideoMetadataInfo
Definition: videoMetadataInfo.h:29
metadatafactory.h
StorageGroup
Definition: storagegroup.h:11
kContentAdult
@ kContentAdult
Definition: metadatacommon.h:63
kArtworkBanner
@ kArtworkBanner
Definition: metadataimagehelper.h:13
kContentMusicVideo
@ kContentMusicVideo
Definition: metadatacommon.h:64
kContentMovie
@ kContentMovie
Definition: metadatacommon.h:61
Video::GetBluray
DTC::BlurayInfo * GetBluray(const QString &Path) override
Definition: video.cpp:399
VideoMetadataListManager::metadata_list
std::list< VideoMetadataPtr > metadata_list
Definition: videometadatalistmanager.h:14
kContentUnknown
@ kContentUnknown
Definition: metadatacommon.h:66
VIDEO_YEAR_DEFAULT
static constexpr uint16_t VIDEO_YEAR_DEFAULT
Definition: videometadata.h:18
VIDEO_BANNER_DEFAULT
const QString VIDEO_BANNER_DEFAULT
Definition: globals.cpp:28
DTC::VideoMetadataInfoList
Definition: videoMetadataInfoList.h:24
kArtworkScreenshot
@ kArtworkScreenshot
Definition: metadataimagehelper.h:14
kContentHomeMovie
@ kContentHomeMovie
Definition: metadatacommon.h:65
FileHash
QString FileHash(const QString &filename)
Definition: mythmiscutil.cpp:548
kArtworkCoverart
@ kArtworkCoverart
Definition: metadataimagehelper.h:11
VIDEO_DIRECTOR_DEFAULT
const QString VIDEO_DIRECTOR_DEFAULT
Definition: globals.cpp:23
VIDEO_SCREENSHOT_DEFAULT
const QString VIDEO_SCREENSHOT_DEFAULT
Definition: globals.cpp:27
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:838
Video::UpdateVideoMetadata
bool UpdateVideoMetadata(int Id, const QString &Title, const QString &SubTitle, const QString &TagLine, const QString &Director, const QString &Studio, const QString &Plot, const QString &Rating, const QString &Inetref, int CollectionRef, const QString &HomePage, int Year, const QDate &ReleaseDate, float UserRating, int Length, int PlayCount, int Season, int Episode, int ShowLevel, const QString &FileName, const QString &Hash, const QString &CoverFile, int ChildID, bool Browse, bool Watched, bool Processed, const QString &PlayCommand, int Category, const QString &Trailer, const QString &Host, const QString &Screenshot, const QString &Banner, const QString &Fanart, const QDate &InsertDate, const QString &ContentType, const QString &Genres, const QString &Cast, const QString &Countries) override
Definition: video.cpp:455
MythStreamInfoList::m_streamInfoList
QVector< MythStreamInfo > m_streamInfoList
Definition: mythavutil.h:103