MythTV  master
v2video.cpp
Go to the documentation of this file.
1 // MythTV
4 #include "libmythbase/mythdb.h"
8 #include "libmythbase/mythversion.h"
15 #include "libmythtv/mythavutil.h"
16 
17 // MythBackend
18 #include "v2artworkInfoList.h"
19 #include "v2castMemberList.h"
20 #include "v2genreList.h"
21 #include "v2serviceUtil.h"
22 #include "v2video.h"
23 
24 
25 // This will be initialised in a thread safe manner on first use
27  (VIDEO_HANDLE, V2Video::staticMetaObject, &V2Video::RegisterCustomTypes))
28 
30 {
31  qRegisterMetaType<V2VideoMetadataInfo*>("V2VideoMetadataInfo");
32  qRegisterMetaType<V2VideoMetadataInfoList*>("V2VideoMetadataInfoList");
33  qRegisterMetaType<V2VideoLookupList*>("V2VideoLookupList");
34  qRegisterMetaType<V2BlurayInfo*>("V2BlurayInfo");
35  qRegisterMetaType<V2VideoStreamInfoList*>("V2VideoStreamInfoList");
36  qRegisterMetaType<V2VideoStreamInfo*>("V2VideoStreamInfo");
37  qRegisterMetaType<V2ArtworkInfoList*>("V2ArtworkInfoList");
38  qRegisterMetaType<V2ArtworkInfo*>("V2ArtworkInfo");
39  qRegisterMetaType<V2CastMemberList*>("V2CastMemberList");
40  qRegisterMetaType<V2CastMember*>("V2CastMember");
41  qRegisterMetaType<V2GenreList*>("V2GenreList");
42  qRegisterMetaType<V2Genre*>("V2Genre");
43  qRegisterMetaType<V2VideoLookupList*>("V2VideoLookupList");
44  qRegisterMetaType<V2VideoLookup*>("V2VideoLookup");
45  qRegisterMetaType<V2ArtworkItem*>("V2ArtworkItem");
46  qRegisterMetaType<V2CutList*>("V2CutList");
47  qRegisterMetaType<V2Cutting*>("V2Cutting");
48 }
49 
51  : MythHTTPService(s_service)
52 {
53 }
54 
56 {
59 
60  if ( !metadata )
61  throw( QString( "No metadata found for selected ID!." ));
62 
63  auto *pVideoMetadataInfo = new V2VideoMetadataInfo();
64 
65  V2FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
66 
67  return pVideoMetadataInfo;
68 }
69 
71 {
74  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
75  mlm->setList(videolist);
76  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byFilename(FileName);
77 
78  if ( !metadata )
79  throw( QString( "No metadata found for selected filename!." ));
80 
81  auto *pVideoMetadataInfo = new V2VideoMetadataInfo();
82 
83  V2FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
84 
85  return pVideoMetadataInfo;
86 }
87 
88 
90 // Get bookmark of a video as a frame number.
92 
94 {
96 
97  query.prepare("SELECT filename "
98  "FROM videometadata "
99  "WHERE intid = :ID ");
100  query.bindValue(":ID", Id);
101 
102  if (!query.exec())
103  {
104  MythDB::DBError("V2Video::GetSavedBookmark", query);
105  return 0;
106  }
107 
108  QString fileName;
109 
110  if (query.next())
111  fileName = query.value(0).toString();
112  else
113  {
114  LOG(VB_GENERAL, LOG_ERR, QString("V2Video/GetSavedBookmark Video id %1 Not found.").arg(Id));
115  return -1;
116  }
117 
118  ProgramInfo pi(fileName,
119  nullptr, // _plot,
120  nullptr, // _title,
121  nullptr, // const QString &_sortTitle,
122  nullptr, // const QString &_subtitle,
123  nullptr, // const QString &_sortSubtitle,
124  nullptr, // const QString &_director,
125  0, // int _season,
126  0, // int _episode,
127  nullptr, // const QString &_inetref,
128  0min, // uint _length_in_minutes,
129  0, // uint _year,
130  nullptr); //const QString &_programid);
131 
132  long ret = pi.QueryBookmark();
133  return ret;
134 }
135 
137 // Get last play pos of a video as a frame number.
139 
141 {
142  MSqlQuery query(MSqlQuery::InitCon());
143 
144  query.prepare("SELECT filename "
145  "FROM videometadata "
146  "WHERE intid = :ID ");
147  query.bindValue(":ID", Id);
148 
149  if (!query.exec())
150  {
151  MythDB::DBError("V2Video::GetLastPlayPos", query);
152  return 0;
153  }
154 
155  QString fileName;
156 
157  if (query.next())
158  fileName = query.value(0).toString();
159  else
160  {
161  LOG(VB_GENERAL, LOG_ERR, QString("V2Video/GetLastPlayPos Video id %1 Not found.").arg(Id));
162  return -1;
163  }
164 
165  ProgramInfo pi(fileName,
166  nullptr, // _plot,
167  nullptr, // _title,
168  nullptr, // const QString &_sortTitle,
169  nullptr, // const QString &_subtitle,
170  nullptr, // const QString &_sortSubtitle,
171  nullptr, // const QString &_director,
172  0, // int _season,
173  0, // int _episode,
174  nullptr, // const QString &_inetref,
175  0min, // uint _length_in_minutes,
176  0, // uint _year,
177  nullptr); //const QString &_programid);
178 
179  long ret = pi.QueryLastPlayPos();
180  return ret;
181 }
182 
183 
184 // If CollapseSubDirs is true, then files in subdirectories are not returned.
185 // Instead, one row is returned for each subdirectory, with the full
186 // directory name in FileName and the lowest part of the directory name
187 // in Title. These directories are returned at the beginning of the list.
188 //
189 // Example: If the database has these files:
190 // one.mkv
191 // dir1/two.mkv
192 // dir1/dir2/two.mkv
193 //
194 // With no Folder name and CollapseSubDirs=true, you get
195 // one.mkv
196 // dir1 Title=dir1
197 //
198 // With Folder=dir1 and CollapseSubDirs=true, you get
199 // dir1/two.mkv
200 // dir1/dir2 Title=dir2
201 
203  const QString &Sort,
204  bool bDescending,
205  int nStartIndex,
206  int nCount,
207  bool CollapseSubDirs )
208 {
209  QString fields = "title,director,studio,plot,rating,year,releasedate,"
210  "userrating,length,playcount,filename,hash,showlevel,"
211  "coverfile,inetref,collectionref,homepage,childid,browse,watched,"
212  "playcommand,category,intid,trailer,screenshot,banner,fanart,"
213  "subtitle,tagline,season,episode,host,insertdate,processed,contenttype";
214 
215  QStringList sortFields = fields.split(',');
216 
218 
219  QString sql = "";
220  QString folder;
221  QString bindValue;
222  if (!Folder.isEmpty())
223  {
224  if (Folder.endsWith('/'))
225  folder = Folder;
226  else
227  folder = Folder + "/";
228  bindValue = folder + "%";
229  sql.append(" WHERE filename LIKE :BINDVALUE ");
230  }
231  sql.append(" ORDER BY ");
232  QString defSeq = " ASC";
233  if (bDescending)
234  defSeq = " DESC";
235 
236  QStringList sortList = Sort.toLower().split(',',Qt::SkipEmptyParts);
237  bool next = false;
238  for (const auto & item : std::as_const(sortList))
239  {
240  QStringList partList = item.split(' ',Qt::SkipEmptyParts);
241  if (partList.empty())
242  continue;
243  QString sort = partList[0];
244  if (sort == "added")
245  sort = "insertdate";
246  else if (sort == "released")
247  sort = "releasedate";
248  if (sortFields.contains(sort))
249  {
250  if (next)
251  sql.append(",");
252  sql.append(sort);
253  if (partList.length() > 1 && partList[1].compare("DESC",Qt::CaseInsensitive) == 0)
254  sql.append(" DESC");
255  else if (partList.length() > 1 && partList[1].compare("ASC",Qt::CaseInsensitive) == 0)
256  sql.append(" ASC");
257  else
258  sql.append(defSeq);
259  next = true;
260  }
261  }
262  if (!next)
263  {
264  sql.append("intid");
265  sql.append(defSeq);
266  }
267 
268  VideoMetadataListManager::loadAllFromDatabase(videolist, sql, bindValue);
269  std::vector<VideoMetadataListManager::VideoMetadataPtr> videos(videolist.begin(), videolist.end());
270 
271  // ----------------------------------------------------------------------
272  // Build Response
273  // ----------------------------------------------------------------------
274 
275  auto *pVideoMetadataInfos = new V2VideoMetadataInfoList();
276  QMap<QString, QString> map;
277  int folderlen = folder.length();
278 
279  nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (int)videos.size() ) : 0;
280  int selectedCount = 0;
281  int totalCount = 0;
282  QString dir;
283 
284  // Make directory list
285  if (CollapseSubDirs)
286  {
287  for( const auto& metadata : videos )
288  {
289  if (!metadata)
290  break;
291  QString fnPart = metadata->GetFilename().mid(folderlen);
292  int slashPos = fnPart.indexOf('/',1);
293  if (slashPos >= 0)
294  {
295  dir = fnPart.mid(0, slashPos);
296  if (!map.contains(dir))
297  {
298  // use toLower here so that lower case are sorted in with
299  // upper case rather than separately at the end.
300  map.insert(dir.toLower(), dir);
301  }
302  }
303  }
304  // Insert directory entries at the front of the list, ordered ascending
305  // or descending, depending on the value of bDescending
306  QMapIterator<QString, QString> it(map);
307  if (bDescending)
308  it.toBack();
309 
310  while (bDescending? it.hasPrevious() : it.hasNext())
311  {
312  if (bDescending)
313  it.previous();
314  else
315  it.next();
316  if (totalCount >= nStartIndex && (nCount == 0 || selectedCount < nCount)) {
317  V2VideoMetadataInfo *pVideoMetadataInfo =
318  pVideoMetadataInfos->AddNewVideoMetadataInfo();
319  pVideoMetadataInfo->setContentType("DIRECTORY");
320  pVideoMetadataInfo->setFileName(folder + it.value());
321  pVideoMetadataInfo->setTitle(it.value());
322  selectedCount++;
323  }
324  totalCount++;
325  }
326  }
327 
328  for( const auto& metadata : videos )
329  {
330  if (!metadata)
331  break;
332 
333  if (CollapseSubDirs)
334  {
335  QString fnPart = metadata->GetFilename().mid(folderlen);
336  int slashPos = fnPart.indexOf('/',1);
337  if (slashPos >= 0)
338  continue;
339  }
340 
341  if (totalCount >= nStartIndex && (nCount == 0 || selectedCount < nCount)) {
342  V2VideoMetadataInfo *pVideoMetadataInfo = pVideoMetadataInfos->AddNewVideoMetadataInfo();
343  V2FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
344  selectedCount++;
345  }
346  totalCount++;
347  }
348 
349  int curPage = 0;
350  int totalPages = 0;
351  if (nCount == 0)
352  totalPages = 1;
353  else
354  totalPages = (int)ceil((float)totalCount / nCount);
355 
356  if (totalPages == 1)
357  curPage = 1;
358  else
359  {
360  curPage = (int)ceil((float)nStartIndex / nCount) + 1;
361  }
362 
363  pVideoMetadataInfos->setStartIndex ( nStartIndex );
364  pVideoMetadataInfos->setCount ( selectedCount );
365  pVideoMetadataInfos->setCurrentPage ( curPage );
366  pVideoMetadataInfos->setTotalPages ( totalPages );
367  pVideoMetadataInfos->setTotalAvailable( totalCount );
368  pVideoMetadataInfos->setAsOf ( MythDate::current() );
369  pVideoMetadataInfos->setVersion ( MYTH_BINARY_VERSION );
370  pVideoMetadataInfos->setProtoVer ( MYTH_PROTO_VERSION );
371 
372  return pVideoMetadataInfos;
373 }
374 
375 
377  const QString &Subtitle,
378  const QString &Inetref,
379  int Season,
380  int Episode,
381  const QString &GrabberType,
382  bool AllowGeneric )
383 {
384  auto *pVideoLookups = new V2VideoLookupList();
385 
386  MetadataLookupList list;
387 
388  auto *factory = new MetadataFactory(nullptr);
389 
390  if (factory)
391  {
392  list = factory->SynchronousLookup(Title, Subtitle,
393  Inetref, Season, Episode,
394  GrabberType, AllowGeneric);
395  }
396 
397  if ( list.empty() )
398  return pVideoLookups;
399 
400  //MetadataLookupList is a reference counted list.
401  //it will delete all its content at its end of life
402  for(const auto & lookup : std::as_const(list))
403  {
404  V2VideoLookup *pVideoLookup = pVideoLookups->AddNewVideoLookup();
405 
406  if (lookup)
407  {
408  pVideoLookup->setTitle(lookup->GetTitle());
409  pVideoLookup->setSubTitle(lookup->GetSubtitle());
410  pVideoLookup->setSeason(lookup->GetSeason());
411  pVideoLookup->setEpisode(lookup->GetEpisode());
412  pVideoLookup->setYear(lookup->GetYear());
413  pVideoLookup->setTagline(lookup->GetTagline());
414  pVideoLookup->setDescription(lookup->GetDescription());
415  pVideoLookup->setCertification(lookup->GetCertification());
416  pVideoLookup->setInetref(lookup->GetInetref());
417  pVideoLookup->setCollectionref(lookup->GetCollectionref());
418  pVideoLookup->setHomePage(lookup->GetHomepage());
419  pVideoLookup->setReleaseDate(
420  QDateTime(lookup->GetReleaseDate(),
421  QTime(0,0),Qt::LocalTime).toUTC());
422  pVideoLookup->setUserRating(lookup->GetUserRating());
423  pVideoLookup->setLength(lookup->GetRuntime().count());
424  pVideoLookup->setLanguage(lookup->GetLanguage());
425  pVideoLookup->setCountries(lookup->GetCountries());
426  pVideoLookup->setPopularity(lookup->GetPopularity());
427  pVideoLookup->setBudget(lookup->GetBudget());
428  pVideoLookup->setRevenue(lookup->GetRevenue());
429  pVideoLookup->setIMDB(lookup->GetIMDB());
430  pVideoLookup->setTMSRef(lookup->GetTMSref());
431 
432  ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
433  ArtworkList::iterator c;
434  for (c = coverartlist.begin(); c != coverartlist.end(); ++c)
435  {
436  V2ArtworkItem *art = pVideoLookup->AddNewArtwork();
437  art->setType("coverart");
438  art->setUrl((*c).url);
439  art->setThumbnail((*c).thumbnail);
440  art->setWidth((*c).width);
441  art->setHeight((*c).height);
442  }
443  ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
444  ArtworkList::iterator f;
445  for (f = fanartlist.begin(); f != fanartlist.end(); ++f)
446  {
447  V2ArtworkItem *art = pVideoLookup->AddNewArtwork();
448  art->setType("fanart");
449  art->setUrl((*f).url);
450  art->setThumbnail((*f).thumbnail);
451  art->setWidth((*f).width);
452  art->setHeight((*f).height);
453  }
454  ArtworkList bannerlist = lookup->GetArtwork(kArtworkBanner);
455  ArtworkList::iterator b;
456  for (b = bannerlist.begin(); b != bannerlist.end(); ++b)
457  {
458  V2ArtworkItem *art = pVideoLookup->AddNewArtwork();
459  art->setType("banner");
460  art->setUrl((*b).url);
461  art->setThumbnail((*b).thumbnail);
462  art->setWidth((*b).width);
463  art->setHeight((*b).height);
464  }
465  ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
466  ArtworkList::iterator s;
467  for (s = screenshotlist.begin(); s != screenshotlist.end(); ++s)
468  {
469  V2ArtworkItem *art = pVideoLookup->AddNewArtwork();
470  art->setType("screenshot");
471  art->setUrl((*s).url);
472  art->setThumbnail((*s).thumbnail);
473  art->setWidth((*s).width);
474  art->setHeight((*s).height);
475  }
476  }
477  }
478 
479  pVideoLookups->setCount ( list.count() );
480  pVideoLookups->setAsOf ( MythDate::current() );
481  pVideoLookups->setVersion ( MYTH_BINARY_VERSION );
482  pVideoLookups->setProtoVer ( MYTH_PROTO_VERSION );
483 
484  delete factory;
485 
486  return pVideoLookups;
487 }
488 
489 
491 {
492  bool bResult = false;
493 
496  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
497  mlm->setList(videolist);
498  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byID(Id);
499 
500  if (metadata)
501  bResult = metadata->DeleteFromDatabase();
502 
503  return bResult;
504 }
505 
506 bool V2Video::AddVideo( const QString &sFileName,
507  const QString &sHostName )
508 {
509  if ( sHostName.isEmpty() )
510  throw( QString( "Host not provided! Local storage is deprecated and "
511  "is not supported by the API." ));
512 
513  if ( sFileName.isEmpty() ||
514  (sFileName.contains("/../")) ||
515  (sFileName.startsWith("../")) )
516  {
517  throw( QString( "Filename not provided, or fails sanity checks!" ));
518  }
519 
520  StorageGroup sgroup("Videos", sHostName);
521 
522  QString fullname = sgroup.FindFile(sFileName);
523 
524  if ( !QFile::exists(fullname) )
525  throw( QString( "Provided filename does not exist!" ));
526 
527  QString hash = FileHash(fullname);
528 
529  if (hash == "NULL")
530  {
531  LOG(VB_GENERAL, LOG_ERR, "Video Hash Failed. Unless this is a DVD or "
532  "Blu-ray, something has probably gone wrong.");
533  hash = "";
534  }
535 
536  VideoMetadata newFile(sFileName, QString(), hash,
542  QString(), QString(), QString(), QString(),
543  QString(), VIDEO_YEAR_DEFAULT,
544  QDate::fromString("0000-00-00","YYYY-MM-DD"),
545  VIDEO_INETREF_DEFAULT, 0, QString(),
547  0.0, VIDEO_RATING_DEFAULT, 0, 0,
548  0, 0,
549  MythDate::current().date(), 0,
551 
552  newFile.SetHost(sHostName);
553  newFile.SaveToDatabase();
554 
555  return true;
556 }
557 
559 //
561 
563  bool bWatched )
564 {
567  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
568  mlm->setList(videolist);
569  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byID(nId);
570 
571  if ( !metadata )
572  return false;
573 
574  metadata->SetWatched(bWatched);
575  metadata->UpdateDatabase();
576 
577  return true;
578 }
579 
581  const QString &sTitle,
582  const QString &sSubTitle,
583  const QString &sTagLine,
584  const QString &sDirector,
585  const QString &sStudio,
586  const QString &sPlot,
587  const QString &sRating,
588  const QString &sInetref,
589  int nCollectionRef,
590  const QString &sHomePage,
591  int nYear,
592  QDate sReleasedate,
593  float fUserRating,
594  int nLength,
595  int nPlayCount,
596  int nSeason,
597  int nEpisode,
598  int nShowLevel,
599  const QString &sFileName,
600  const QString &sHash,
601  const QString &sCoverFile,
602  int nChildID,
603  bool bBrowse,
604  bool bWatched,
605  bool bProcessed,
606  const QString &sPlayCommand,
607  int nCategory,
608  const QString &sTrailer,
609  const QString &sHost,
610  const QString &sScreenshot,
611  const QString &sBanner,
612  const QString &sFanart,
613  QDate sInsertDate,
614  const QString &sContentType,
615  const QString &sGenres,
616  const QString &sCast,
617  const QString &sCountries)
618 {
619  bool update_required = false;
622  QScopedPointer<VideoMetadataListManager> mlm(new VideoMetadataListManager());
623  mlm->setList(videolist);
624  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byID(nId);
625 
626  if (!metadata)
627  {
628  LOG(VB_GENERAL, LOG_ERR, QString("UpdateVideoMetadata: Id=%1 not found")
629  .arg(nId));
630  return false;
631  }
632 
633  if (HAS_PARAMv2("Title"))
634  {
635  metadata->SetTitle(sTitle);
636  update_required = true;
637  }
638 
639  if (HAS_PARAMv2("SubTitle"))
640  {
641  metadata->SetSubtitle(sSubTitle);
642  update_required = true;
643  }
644 
645  if (HAS_PARAMv2("TagLine"))
646  {
647  metadata->SetTagline(sTagLine);
648  update_required = true;
649  }
650 
651  if (HAS_PARAMv2("Director"))
652  {
653  metadata->SetDirector(sDirector);
654  update_required = true;
655  }
656 
657  if (HAS_PARAMv2("Studio"))
658  {
659  metadata->SetStudio(sStudio);
660  update_required = true;
661  }
662 
663  if (HAS_PARAMv2("Plot"))
664  {
665  metadata->SetPlot(sPlot);
666  update_required = true;
667  }
668 
669  if (HAS_PARAMv2("UserRating"))
670  {
671  metadata->SetUserRating(fUserRating);
672  update_required = true;
673  }
674 
675  if (HAS_PARAMv2("Inetref"))
676  {
677  metadata->SetInetRef(sInetref);
678  update_required = true;
679  }
680 
681  if (HAS_PARAMv2("CollectionRef"))
682  {
683  metadata->SetCollectionRef(nCollectionRef);
684  update_required = true;
685  }
686 
687  if (HAS_PARAMv2("HomePage"))
688  {
689  metadata->SetHomepage(sHomePage);
690  update_required = true;
691  }
692 
693  if (HAS_PARAMv2("Year"))
694  {
695  metadata->SetYear(nYear);
696  update_required = true;
697  }
698 
699  if (HAS_PARAMv2("ReleaseDate"))
700  {
701  metadata->SetReleaseDate(sReleasedate);
702  update_required = true;
703  }
704 
705  if (HAS_PARAMv2("Rating"))
706  {
707  metadata->SetRating(sRating);
708  update_required = true;
709  }
710 
711  if (HAS_PARAMv2("Length"))
712  {
713  metadata->SetLength(std::chrono::minutes(nLength));
714  update_required = true;
715  }
716 
717  if (HAS_PARAMv2("PlayCount"))
718  {
719  metadata->SetPlayCount(nPlayCount);
720  update_required = true;
721  }
722 
723  if (HAS_PARAMv2("Season"))
724  {
725  metadata->SetSeason(nSeason);
726  update_required = true;
727  }
728 
729  if (HAS_PARAMv2("Episode"))
730  {
731  metadata->SetEpisode(nEpisode);
732  update_required = true;
733  }
734 
735  if (HAS_PARAMv2("ShowLevel"))
736  {
737  metadata->SetShowLevel(ParentalLevel::Level(nShowLevel));
738  update_required = true;
739  }
740 
741  if (HAS_PARAMv2("FileName"))
742  {
743  metadata->SetFilename(sFileName);
744  update_required = true;
745  }
746 
747  if (HAS_PARAMv2("Hash"))
748  {
749  metadata->SetHash(sHash);
750  update_required = true;
751  }
752 
753  if (HAS_PARAMv2("CoverFile"))
754  {
755  metadata->SetCoverFile(sCoverFile);
756  update_required = true;
757  }
758 
759  if (HAS_PARAMv2("ChildID"))
760  {
761  metadata->SetChildID(nChildID);
762  update_required = true;
763  }
764 
765  if (HAS_PARAMv2("Browse"))
766  {
767  metadata->SetBrowse(bBrowse);
768  update_required = true;
769  }
770 
771  if (HAS_PARAMv2("Watched"))
772  {
773  metadata->SetWatched(bWatched);
774  update_required = true;
775  }
776 
777  if (HAS_PARAMv2("Processed"))
778  {
779  metadata->SetProcessed(bProcessed);
780  update_required = true;
781  }
782 
783  if (HAS_PARAMv2("PlayCommand"))
784  {
785  metadata->SetPlayCommand(sPlayCommand);
786  update_required = true;
787  }
788 
789  if (HAS_PARAMv2("Category"))
790  {
791  metadata->SetCategoryID(nCategory);
792  update_required = true;
793  }
794 
795  if (HAS_PARAMv2("Trailer"))
796  {
797  metadata->SetTrailer(sTrailer);
798  update_required = true;
799  }
800 
801  if (HAS_PARAMv2("Host"))
802  {
803  metadata->SetHost(sHost);
804  update_required = true;
805  }
806 
807  if (HAS_PARAMv2("Screenshot"))
808  {
809  metadata->SetScreenshot(sScreenshot);
810  update_required = true;
811  }
812 
813  if (HAS_PARAMv2("Banner"))
814  {
815  metadata->SetBanner(sBanner);
816  update_required = true;
817  }
818 
819  if (HAS_PARAMv2("Fanart"))
820  {
821  metadata->SetFanart(sFanart);
822  update_required = true;
823  }
824 
825  if (HAS_PARAMv2("InsertDate"))
826  {
827  metadata->SetInsertdate(sInsertDate);
828  update_required = true;
829  }
830 
831  if (HAS_PARAMv2("ContentType"))
832  {
833  // valid values for ContentType are 'MOVIE','TELEVISION','ADULT','MUSICVIDEO','HOMEVIDEO'
834  VideoContentType contentType = kContentUnknown;
835  if (sContentType == "MOVIE")
836  contentType = kContentMovie;
837 
838  if (sContentType == "TELEVISION")
839  contentType = kContentTelevision;
840 
841  if (sContentType == "ADULT")
842  contentType = kContentAdult;
843 
844  if (sContentType == "MUSICVIDEO")
845  contentType = kContentMusicVideo;
846 
847  if (sContentType == "HOMEVIDEO")
848  contentType = kContentHomeMovie;
849 
850  if (contentType != kContentUnknown)
851  {
852  metadata->SetContentType(contentType);
853  update_required = true;
854  }
855  else
856  {
857  LOG(VB_GENERAL, LOG_ERR, QString("UpdateVideoMetadata: Ignoring unknown ContentType: %1").arg(sContentType));
858  }
859  }
860 
861  if (HAS_PARAMv2("Genres"))
862  {
864  QStringList genresList = sGenres.split(',', Qt::SkipEmptyParts);
865  std::transform(genresList.cbegin(), genresList.cend(), std::back_inserter(genres),
866  [](const QString& name)
867  {return VideoMetadata::genre_list::value_type(-1, name.simplified());} );
868 
869  metadata->SetGenres(genres);
870  update_required = true;
871  }
872 
873  if (HAS_PARAMv2("Cast"))
874  {
876  QStringList castList = sCast.split(',', Qt::SkipEmptyParts);
877  std::transform(castList.cbegin(), castList.cend(), std::back_inserter(cast),
878  [](const QString& name)
879  {return VideoMetadata::cast_list::value_type(-1, name.simplified());} );
880 
881  metadata->SetCast(cast);
882  update_required = true;
883  }
884 
885  if (HAS_PARAMv2("Countries"))
886  {
887  VideoMetadata::country_list countries;
888  QStringList countryList = sCountries.split(',', Qt::SkipEmptyParts);
889  std::transform(countryList.cbegin(), countryList.cend(), std::back_inserter(countries),
890  [](const QString& name)
891  {return VideoMetadata::country_list::value_type(-1, name.simplified());} );
892 
893  metadata->SetCountries(countries);
894  update_required = true;
895  }
896 
897  if (update_required)
898  metadata->UpdateDatabase();
899 
900  return true;
901 }
902 
904 // Set bookmark of a video as a frame number.
906 
907 bool V2Video::SetSavedBookmark( int Id, long Offset )
908 {
909  MSqlQuery query(MSqlQuery::InitCon());
910 
911  query.prepare("SELECT filename "
912  "FROM videometadata "
913  "WHERE intid = :ID ");
914  query.bindValue(":ID", Id);
915 
916  if (!query.exec())
917  {
918  MythDB::DBError("Video::SetSavedBookmark", query);
919  return false;
920  }
921 
922  QString fileName;
923 
924  if (query.next())
925  fileName = query.value(0).toString();
926  else
927  {
928  LOG(VB_GENERAL, LOG_ERR, QString("Video/SetSavedBookmark Video id %1 Not found.").arg(Id));
929  return false;
930  }
931 
932  ProgramInfo pi(fileName,
933  nullptr, // _plot,
934  nullptr, // _title,
935  nullptr, // const QString &_sortTitle,
936  nullptr, // const QString &_subtitle,
937  nullptr, // const QString &_sortSubtitle,
938  nullptr, // const QString &_director,
939  0, // int _season,
940  0, // int _episode,
941  nullptr, // const QString &_inetref,
942  0min, // uint _length_in_minutes,
943  0, // uint _year,
944  nullptr); //const QString &_programid);
945 
946  pi.SaveBookmark(Offset);
947  return true;
948 }
949 
951 // Set bookmark of a video as a frame number.
953 
954 bool V2Video::SetLastPlayPos( int Id, long Offset )
955 {
956  MSqlQuery query(MSqlQuery::InitCon());
957 
958  query.prepare("SELECT filename "
959  "FROM videometadata "
960  "WHERE intid = :ID ");
961  query.bindValue(":ID", Id);
962 
963  if (!query.exec())
964  {
965  MythDB::DBError("Video::SetLastPlayPos", query);
966  return false;
967  }
968 
969  QString fileName;
970 
971  if (query.next())
972  fileName = query.value(0).toString();
973  else
974  {
975  LOG(VB_GENERAL, LOG_ERR, QString("Video/SetLastPlayPos Video id %1 Not found.").arg(Id));
976  return false;
977  }
978 
979  ProgramInfo pi(fileName,
980  nullptr, // _plot,
981  nullptr, // _title,
982  nullptr, // const QString &_sortTitle,
983  nullptr, // const QString &_subtitle,
984  nullptr, // const QString &_sortSubtitle,
985  nullptr, // const QString &_director,
986  0, // int _season,
987  0, // int _episode,
988  nullptr, // const QString &_inetref,
989  0min, // uint _length_in_minutes,
990  0, // uint _year,
991  nullptr); //const QString &_programid);
992 
993  pi.SaveLastPlayPos(Offset);
994  return true;
995 }
996 
997 
998 V2BlurayInfo* V2Video::GetBluray( const QString &sPath )
999 {
1000  QString path = sPath;
1001 
1002  if (sPath.isEmpty())
1003  path = gCoreContext->GetSetting( "BluRayMountpoint", "/media/cdrom");
1004 
1005  LOG(VB_GENERAL, LOG_NOTICE,
1006  QString("Parsing Blu-ray at path: %1 ").arg(path));
1007 
1008  auto *bdmeta = new BlurayMetadata(path);
1009 
1010  if ( !bdmeta )
1011  throw( QString( "Unable to open Blu-ray Metadata Parser!" ));
1012 
1013  if ( !bdmeta->OpenDisc() )
1014  throw( QString( "Unable to open Blu-ray Disc/Path!" ));
1015 
1016  if ( !bdmeta->ParseDisc() )
1017  throw( QString( "Unable to parse metadata from Blu-ray Disc/Path!" ));
1018 
1019  auto *pBlurayInfo = new V2BlurayInfo();
1020 
1021  pBlurayInfo->setPath(path);
1022  pBlurayInfo->setTitle(bdmeta->GetTitle());
1023  pBlurayInfo->setAltTitle(bdmeta->GetAlternateTitle());
1024  pBlurayInfo->setDiscLang(bdmeta->GetDiscLanguage());
1025  pBlurayInfo->setDiscNum(bdmeta->GetCurrentDiscNumber());
1026  pBlurayInfo->setTotalDiscNum(bdmeta->GetTotalDiscNumber());
1027  pBlurayInfo->setTitleCount(bdmeta->GetTitleCount());
1028  pBlurayInfo->setThumbCount(bdmeta->GetThumbnailCount());
1029  pBlurayInfo->setTopMenuSupported(bdmeta->GetTopMenuSupported());
1030  pBlurayInfo->setFirstPlaySupported(bdmeta->GetFirstPlaySupported());
1031  pBlurayInfo->setNumHDMVTitles(bdmeta->GetNumHDMVTitles());
1032  pBlurayInfo->setNumBDJTitles(bdmeta->GetNumBDJTitles());
1033  pBlurayInfo->setNumUnsupportedTitles(bdmeta->GetNumUnsupportedTitles());
1034  pBlurayInfo->setAACSDetected(bdmeta->GetAACSDetected());
1035  pBlurayInfo->setLibAACSDetected(bdmeta->GetLibAACSDetected());
1036  pBlurayInfo->setAACSHandled(bdmeta->GetAACSHandled());
1037  pBlurayInfo->setBDPlusDetected(bdmeta->GetBDPlusDetected());
1038  pBlurayInfo->setLibBDPlusDetected(bdmeta->GetLibBDPlusDetected());
1039  pBlurayInfo->setBDPlusHandled(bdmeta->GetBDPlusHandled());
1040 
1041  QStringList thumbs = bdmeta->GetThumbnails();
1042  if (!thumbs.empty())
1043  pBlurayInfo->setThumbPath(thumbs.at(0));
1044 
1045  delete bdmeta;
1046 
1047  return pBlurayInfo;
1048 }
1049 
1050 
1052 // Jun 3, 2020
1053 // Service to get stream info for all streams in a media file.
1054 // This gets some basic info. If anything more is needed it can be added,
1055 // depending on whether it is available from ffmpeg avformat apis.
1056 // See the MythStreamInfoList class for the code that uses avformat to
1057 // extract the information.
1059 
1061  ( const QString &storageGroup,
1062  const QString &FileName )
1063 {
1064 
1065  // Search for the filename
1066 
1067  StorageGroup storage( storageGroup );
1068  QString sFullFileName = storage.FindFile( FileName );
1069  MythStreamInfoList infos(sFullFileName);
1070 
1071  // The constructor of this class reads the file and gets the needed
1072  // information.
1073  auto *pVideoStreamInfos = new V2VideoStreamInfoList();
1074 
1075  pVideoStreamInfos->setCount ( infos.m_streamInfoList.size() );
1076  pVideoStreamInfos->setAsOf ( MythDate::current() );
1077  pVideoStreamInfos->setVersion ( MYTH_BINARY_VERSION );
1078  pVideoStreamInfos->setProtoVer ( MYTH_PROTO_VERSION );
1079  pVideoStreamInfos->setErrorCode ( infos.m_errorCode );
1080  pVideoStreamInfos->setErrorMsg ( infos.m_errorMsg );
1081 
1082  for (const auto & info : std::as_const(infos.m_streamInfoList))
1083  {
1084  V2VideoStreamInfo *pVideoStreamInfo = pVideoStreamInfos->AddNewVideoStreamInfo();
1085  pVideoStreamInfo->setCodecType ( QString(QChar(info.m_codecType)) );
1086  pVideoStreamInfo->setCodecName ( info.m_codecName );
1087  pVideoStreamInfo->setWidth ( info.m_width );
1088  pVideoStreamInfo->setHeight ( info.m_height );
1089  pVideoStreamInfo->setAspectRatio ( info.m_SampleAspectRatio );
1090  pVideoStreamInfo->setFieldOrder ( info.m_fieldOrder );
1091  pVideoStreamInfo->setFrameRate ( info.m_frameRate );
1092  pVideoStreamInfo->setAvgFrameRate ( info.m_avgFrameRate );
1093  pVideoStreamInfo->setChannels ( info.m_channels );
1094  pVideoStreamInfo->setDuration ( info.m_duration );
1095 
1096  }
1097  return pVideoStreamInfos;
1098 }
1099 
1101 // October 26,2022
1102 // Support for Cut List for Videos
1104 
1106  const QString &offsettype )
1107 {
1108  MSqlQuery query(MSqlQuery::InitCon());
1109 
1110  query.prepare("SELECT filename "
1111  "FROM videometadata "
1112  "WHERE intid = :ID ");
1113  query.bindValue(":ID", Id);
1114 
1115  if (!query.exec())
1116  {
1117  MythDB::DBError("V2Video::GetVideoCommBreak", query);
1118  throw QString("Database Error.");
1119  }
1120 
1121  QString fileName;
1122 
1123  if (query.next())
1124  fileName = query.value(0).toString();
1125  else
1126  {
1127  LOG(VB_GENERAL, LOG_ERR, QString("V2Video/GetVideoCommBreak Video id %1 Not found.").arg(Id));
1128  throw QString("Video Not Found.");
1129  }
1130 
1131  ProgramInfo pi(fileName,
1132  nullptr, // _plot,
1133  nullptr, // _title,
1134  nullptr, // const QString &_sortTitle,
1135  nullptr, // const QString &_subtitle,
1136  nullptr, // const QString &_sortSubtitle,
1137  nullptr, // const QString &_director,
1138  0, // int _season,
1139  0, // int _episode,
1140  nullptr, // const QString &_inetref,
1141  0min, // uint _length_in_minutes,
1142  0, // uint _year,
1143  nullptr); //const QString &_programid);
1144 
1145 
1146  int marktype = 0;
1147 
1148  auto* pCutList = new V2CutList();
1149  if (offsettype.toLower() == "position")
1150  marktype = 1;
1151  else if (offsettype.toLower() == "duration")
1152  marktype = 2;
1153  else
1154  marktype = 0;
1155 
1156  V2FillCutList(pCutList, &pi, marktype);
1157 
1158  return pCutList;
1159 }
1160 
1162 // October 26,2022
1163 // Support for Commercial Break List for Videos
1165 
1167  const QString &offsettype )
1168 {
1169  MSqlQuery query(MSqlQuery::InitCon());
1170 
1171  query.prepare("SELECT filename "
1172  "FROM videometadata "
1173  "WHERE intid = :ID ");
1174  query.bindValue(":ID", Id);
1175 
1176  if (!query.exec())
1177  {
1178  MythDB::DBError("V2Video::GetVideoCommBreak", query);
1179  throw QString("Database Error.");
1180  }
1181 
1182  QString fileName;
1183 
1184  if (query.next())
1185  fileName = query.value(0).toString();
1186  else
1187  {
1188  LOG(VB_GENERAL, LOG_ERR, QString("V2Video/GetVideoCommBreak Video id %1 Not found.").arg(Id));
1189  throw QString("Video Not Found.");
1190  }
1191 
1192  ProgramInfo pi(fileName,
1193  nullptr, // _plot,
1194  nullptr, // _title,
1195  nullptr, // const QString &_sortTitle,
1196  nullptr, // const QString &_subtitle,
1197  nullptr, // const QString &_sortSubtitle,
1198  nullptr, // const QString &_director,
1199  0, // int _season,
1200  0, // int _episode,
1201  nullptr, // const QString &_inetref,
1202  0min, // uint _length_in_minutes,
1203  0, // uint _year,
1204  nullptr); //const QString &_programid);
1205 
1206 
1207  int marktype = 0;
1208 
1209  auto* pCutList = new V2CutList();
1210  if (offsettype.toLower() == "position")
1211  marktype = 1;
1212  else if (offsettype.toLower() == "duration")
1213  marktype = 2;
1214  else
1215  marktype = 0;
1216 
1217  V2FillCommBreak(pCutList, &pi, marktype);
1218 
1219  return pCutList;
1220 }
MythHTTPService::HAS_PARAMv2
bool HAS_PARAMv2(const QString &p)
Definition: mythhttpservice.h:36
V2VideoLookup::AddNewArtwork
V2ArtworkItem * AddNewArtwork()
Definition: v2videoLookupInfo.h:119
MythStreamInfoList::m_errorMsg
QString m_errorMsg
Definition: mythavutil.h:102
BlurayMetadata
Definition: bluraymetadata.h:25
kContentAdult
@ kContentAdult
Definition: metadatacommon.h:63
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
VideoMetadata
Definition: videometadata.h:24
V2VideoStreamInfoList
Definition: v2videoStreamInfoList.h:20
v2video.h
V2Video::AddVideo
static bool AddVideo(const QString &FileName, const QString &HostName)
Definition: v2video.cpp:506
V2Video::GetVideoCommBreak
static V2CutList * GetVideoCommBreak(int Id, const QString &OffsetType)
Definition: v2video.cpp:1166
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:2674
V2VideoLookupList
Definition: v2videoLookupInfoList.h:21
videometadata.h
mythdb.h
V2Video::LookupVideo
static V2VideoLookupList * LookupVideo(const QString &Title, const QString &Subtitle, const QString &Inetref, int Season, int Episode, const QString &GrabberType, bool AllowGeneric)
Definition: v2video.cpp:376
VideoMetadataListManager
Definition: videometadatalistmanager.h:10
V2FillCommBreak
void V2FillCommBreak(V2CutList *pCutList, ProgramInfo *rInfo, int marktype)
Definition: v2serviceUtil.cpp:661
simple_ref_ptr
Definition: quicksp.h:24
V2Video::GetBluray
static V2BlurayInfo * GetBluray(const QString &Path)
Definition: v2video.cpp:998
ArtworkList
QList< ArtworkInfo > ArtworkList
Definition: metadataimagehelper.h:30
V2FillVideoMetadataInfo
void V2FillVideoMetadataInfo(V2VideoMetadataInfo *pVideoMetadataInfo, const VideoMetadataListManager::VideoMetadataPtr &pMetadata, bool bDetails)
Definition: v2serviceUtil.cpp:390
StorageGroup::FindFile
QString FindFile(const QString &filename)
Definition: storagegroup.cpp:597
MythStreamInfoList
Definition: mythavutil.h:98
V2BlurayInfo
Definition: v2blurayInfo.h:20
V2ArtworkItem
Definition: v2videoLookupInfo.h:22
kContentMusicVideo
@ kContentMusicVideo
Definition: metadatacommon.h:64
xbmcvfs.exists
bool exists(str path)
Definition: xbmcvfs.py:51
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
mythdbcon.h
VideoMetadata::country_list
std::vector< country_entry > country_list
Definition: videometadata.h:33
mythhttpmetaservice.h
V2Video::SetLastPlayPos
static bool SetLastPlayPos(int Id, long Offset)
Definition: v2video.cpp:954
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
V2Video::GetVideo
static V2VideoMetadataInfo * GetVideo(int Id)
Definition: v2video.cpp:55
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
VideoMetadata::genre_list
std::vector< genre_entry > genre_list
Definition: videometadata.h:32
GrabberType
GrabberType
Definition: metadatagrabber.h:20
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
V2VideoStreamInfo
Definition: v2videoStreamInfo.h:21
V2VideoLookup
Definition: v2videoLookupInfo.h:56
kArtworkScreenshot
@ kArtworkScreenshot
Definition: metadataimagehelper.h: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:2798
MythStreamInfoList::m_errorCode
int m_errorCode
Definition: mythavutil.h:101
V2Video::GetStreamInfo
static V2VideoStreamInfoList * GetStreamInfo(const QString &StorageGroup, const QString &FileName)
Definition: v2video.cpp:1061
V2Video::SetSavedBookmark
static bool SetSavedBookmark(int Id, long Offset)
Definition: v2video.cpp:907
ParentalLevel::plLowest
@ plLowest
Definition: parentalcontrols.h:13
kArtworkCoverart
@ kArtworkCoverart
Definition: metadataimagehelper.h:11
programinfo.h
kArtworkFanart
@ kArtworkFanart
Definition: metadataimagehelper.h:12
mythlogging.h
V2Video::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, 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, QDate InsertDate, const QString &ContentType, const QString &Genres, const QString &Cast, const QString &Countries)
Definition: v2video.cpp:580
v2serviceUtil.h
globals.h
RefCountedList< MetadataLookup >
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
kArtworkBanner
@ kArtworkBanner
Definition: metadataimagehelper.h:13
V2Video::RemoveVideoFromDB
static bool RemoveVideoFromDB(int Id)
Definition: v2video.cpp:490
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
VideoMetadata::SaveToDatabase
void SaveToDatabase()
Definition: videometadata.cpp:1949
V2Video::GetVideoList
static V2VideoMetadataInfoList * GetVideoList(const QString &Folder, const QString &Sort, bool Descending, int StartIndex, int Count, bool CollapseSubDirs)
Definition: v2video.cpp:202
VIDEO_COVERFILE_DEFAULT
const QString VIDEO_COVERFILE_DEFAULT
Definition: globals.cpp:25
Q_GLOBAL_STATIC_WITH_ARGS
Q_GLOBAL_STATIC_WITH_ARGS(MythHTTPMetaService, s_service,(VIDEO_HANDLE, V2Video::staticMetaObject, &V2Video::RegisterCustomTypes)) void V2Video
Definition: v2video.cpp:26
VIDEO_PLOT_DEFAULT
const QString VIDEO_PLOT_DEFAULT
Definition: globals.cpp:32
VIDEO_HANDLE
#define VIDEO_HANDLE
Definition: v2video.h:14
V2CutList
Definition: v2cutList.h:21
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
MythHTTPService
Definition: mythhttpservice.h:19
V2Video::V2Video
V2Video()
Definition: v2video.cpp:50
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
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
v2artworkInfoList.h
kContentUnknown
@ kContentUnknown
Definition: metadatacommon.h:66
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
V2Video::GetLastPlayPos
static long GetLastPlayPos(int Id)
Definition: v2video.cpp:140
mythmiscutil.h
V2Video::UpdateVideoWatchedStatus
static bool UpdateVideoWatchedStatus(int Id, bool Watched)
Definition: v2video.cpp:562
mythcorecontext.h
VideoMetadata::cast_list
std::vector< cast_entry > cast_list
Definition: videometadata.h:34
kContentTelevision
@ kContentTelevision
Definition: metadatacommon.h:62
VideoMetadata::SetHost
void SetHost(const QString &host)
Definition: videometadata.cpp:1839
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
VIDEO_RATING_DEFAULT
const QString VIDEO_RATING_DEFAULT
Definition: globals.cpp:30
V2FillCutList
void V2FillCutList(V2CutList *pCutList, ProgramInfo *rInfo, int marktype)
Definition: v2serviceUtil.cpp:619
VideoMetadataListManager::loadOneFromDatabase
static VideoMetadataPtr loadOneFromDatabase(uint id)
Definition: videometadatalistmanager.cpp:111
bluraymetadata.h
mythavutil.h
V2Video::RegisterCustomTypes
static void RegisterCustomTypes()
metadatafactory.h
StorageGroup
Definition: storagegroup.h:11
V2VideoMetadataInfoList
Definition: v2videoMetadataInfoList.h:20
VideoContentType
VideoContentType
Definition: metadatacommon.h:60
VideoMetadataListManager::metadata_list
std::list< VideoMetadataPtr > metadata_list
Definition: videometadatalistmanager.h:14
v2genreList.h
azlyrics.info
dictionary info
Definition: azlyrics.py:7
ProgramInfo::QueryLastPlayPos
uint64_t QueryLastPlayPos(void) const
Gets any lastplaypos position in database, unless the ignore lastplaypos flag is set.
Definition: programinfo.cpp:2825
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
ParentalLevel::Level
Level
Definition: parentalcontrols.h:12
kContentHomeMovie
@ kContentHomeMovie
Definition: metadatacommon.h:65
V2Video::GetVideoByFileName
static V2VideoMetadataInfo * GetVideoByFileName(const QString &FileName)
Definition: v2video.cpp:70
FileHash
QString FileHash(const QString &filename)
Definition: mythmiscutil.cpp:548
V2Video::GetSavedBookmark
static long GetSavedBookmark(int Id)
Definition: v2video.cpp:93
v2castMemberList.h
MythHTTPMetaService
Definition: mythhttpmetaservice.h:10
VIDEO_DIRECTOR_DEFAULT
const QString VIDEO_DIRECTOR_DEFAULT
Definition: globals.cpp:23
kContentMovie
@ kContentMovie
Definition: metadatacommon.h:61
V2Video::GetVideoCutList
static V2CutList * GetVideoCutList(int Id, const QString &OffsetType)
Definition: v2video.cpp:1105
ProgramInfo::SaveLastPlayPos
void SaveLastPlayPos(uint64_t frame)
TODO Move to RecordingInfo.
Definition: programinfo.cpp:2711
VIDEO_SCREENSHOT_DEFAULT
const QString VIDEO_SCREENSHOT_DEFAULT
Definition: globals.cpp:27
V2VideoMetadataInfo
Definition: v2videoMetadataInfo.h:9
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:902
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
MythStreamInfoList::m_streamInfoList
QVector< MythStreamInfo > m_streamInfoList
Definition: mythavutil.h:103