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