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