11#include <QApplication>
12#include <QDomDocument>
18#include <QRegularExpression>
23#include "libmythbase/mythconfig.h"
78#define DEBUG_CHANNEL_PREFIX 0
79#define DEBUG_ACTIONS 0
81#define LOC QString("TV::%1(): ").arg(__func__)
93 return (dt1 > dt2 ? 1 : -1);
123 query.
prepare(
"SELECT COUNT(cardid) FROM capturecard;");
125 count = query.
value(0).toInt();
127 LOG(VB_RECORD, LOG_INFO,
128 "ConfiguredTunerCards() = " + QString::number(count));
142 static QMutex s_lock;
143 static TV* s_tv =
nullptr;
144 QMutexLocker locker(&s_lock);
156 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Ref count error");
202 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Already have a player");
208 auto flags =
static_cast<PlayerFlags>(playerflags);
241 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
246 MaxWait = (MaxWait <= 0ms) ? 20s : MaxWait;
248 MaxWait = std::chrono::milliseconds::max();
258 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
259 QString(
"StartPlaying(): took %1 ms to start player.")
260 .arg(
t.elapsed().count()));
263 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
295 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Already have a TV object.");
300 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
303 bool quitAll =
false;
304 bool showDialogs =
true;
305 bool playCompleted =
false;
307 bool startSysEventSent =
false;
308 bool startLivetvEventSent =
false;
321 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed initializing TV");
343 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- begin");
348 else if (!startSysEventSent)
350 startSysEventSent =
true;
354 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- end");
358 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- begin");
359 if (!tv->
LiveTV(showDialogs, Selection))
364 else if (!startSysEventSent)
366 startSysEventSent =
true;
367 startLivetvEventSent =
true;
371 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- end");
376 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners configured");
378 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners free for live tv");
389 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Entering main playback loop.");
391 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Exiting main playback loop.");
399 curProgram = nextProgram;
413 quitAll |= !playerError.isEmpty();
416 QCoreApplication::processEvents();
420 playCompleted =
true;
430 if (startSysEventSent)
438 list.push_back(allowrerecord ?
"1" :
"0");
439 MythEvent me(
"LOCAL_PBB_DELETE_RECORDINGS", list);
450 else if (startSysEventSent)
455 if (!playerError.isEmpty())
465 if (startLivetvEventSent)
468 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
470 return playCompleted;
480 if (name ==
"playbackbox")
482 else if (name ==
"viewscheduled")
484 else if (name ==
"programguide")
486 else if (name ==
"programfinder")
488 else if (name ==
"scheduleeditor")
490 else if (name ==
"programlist")
497 "Play Program"),
"P,Media Play");
499 "Stop Program"),
"");
501 "Toggle recording status of current program"),
"R");
503 "Page the program guide back one day"),
"Home,Media Previous");
505 "Page the program guide forward one day"),
"End,Media Next");
507 "Page the program guide left"),
",,<,Ctrl+B,Media Rewind");
509 "Page the program guide right"),
">,.,Ctrl+F,Media Fast Forward");
511 "Toggle the current channel as a favorite"),
"?");
513 "Reverse the channel order in the program guide"),
"");
515 "Show the Program Guide"),
"S");
517 "Show the Program Finder"),
"#");
519 "Show the Channel Search"),
"");
520 REG_KEY(
"TV Frontend",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
521 "Cycle through channel groups and all channels in the "
522 "program guide."),
"/");
523 REG_KEY(
"TV Frontend",
"CHANUPDATE", QT_TRANSLATE_NOOP(
"MythControls",
524 "Switch channels without exiting guide in Live TV mode."),
"X");
526 "Volume down"),
"[,{,F10,Volume Down");
528 "Volume up"),
"],},F11,Volume Up");
530 "Mute"),
"|,\\,F9,Volume Mute");
531 REG_KEY(
"TV Frontend",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
532 "Cycle audio channels"),
"");
533 REG_KEY(
"TV Frontend",
"RANKINC", QT_TRANSLATE_NOOP(
"MythControls",
534 "Increase program or channel rank"),
"Right");
535 REG_KEY(
"TV Frontend",
"RANKDEC", QT_TRANSLATE_NOOP(
"MythControls",
536 "Decrease program or channel rank"),
"Left");
537 REG_KEY(
"TV Frontend",
"UPCOMING", QT_TRANSLATE_NOOP(
"MythControls",
538 "List upcoming episodes"),
"O");
540 "List scheduled upcoming episodes"),
"");
542 "List previously recorded episodes"),
"");
543 REG_KEY(
"TV Frontend",
"DETAILS", QT_TRANSLATE_NOOP(
"MythControls",
544 "Show details"),
"U");
545 REG_KEY(
"TV Frontend",
"VIEWINPUT", QT_TRANSLATE_NOOP(
"MythControls",
546 "Switch Recording Input view"),
"C");
547 REG_KEY(
"TV Frontend",
"CUSTOMEDIT", QT_TRANSLATE_NOOP(
"MythControls",
548 "Edit Custom Record Rule"),
"");
549 REG_KEY(
"TV Frontend",
"CHANGERECGROUP", QT_TRANSLATE_NOOP(
"MythControls",
550 "Change Recording Group"),
"");
551 REG_KEY(
"TV Frontend",
"CHANGEGROUPVIEW", QT_TRANSLATE_NOOP(
"MythControls",
552 "Change Group View"),
"");
554 "List recorded episodes"),
"");
574 if (selectKeys !=
"?")
577 togBkmKeys = selectKeys;
579 bkmKeys = selectKeys;
583 "Add Bookmark"), bkmKeys);
585 "Toggle Bookmark"), togBkmKeys);
586 REG_KEY(
"TV Playback",
"BACK", QT_TRANSLATE_NOOP(
"MythControls",
587 "Exit or return to DVD menu"),
"Esc,Back");
589 "Playback Compact Menu"),
"Alt+M");
591 "Clear OSD"),
"Backspace");
593 "Pause"),
"P,Space,Media Play");
595 "Fast Forward"),
"Right");
599 "Arbitrary Seek"),
"*");
601 "Seek to a position in seconds"),
"");
603 "Channel up"),
"Up");
605 "Channel down"),
"Down");
606 REG_KEY(
"TV Playback",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
607 "Switch to the next favorite channel"),
"/");
608 REG_KEY(
"TV Playback",
"PREVCHAN", QT_TRANSLATE_NOOP(
"MythControls",
609 "Switch to the previous channel"),
"H");
611 "Jump ahead"),
"PgDown");
613 "Jump back"),
"PgUp");
614 REG_KEY(
"TV Playback",
"INFOWITHCUTLIST", QT_TRANSLATE_NOOP(
"MythControls",
615 "Info utilizing cutlist"),
"");
617 "Jump to bookmark"),
"K");
618 REG_KEY(
"TV Playback",
"FFWDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
619 "Fast Forward (Sticky) or Forward one second while paused"),
">,.,Ctrl+F,Media Fast Forward");
620 REG_KEY(
"TV Playback",
"RWNDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
621 "Rewind (Sticky) or Rewind one second while paused"),
",,<,Ctrl+B,Media Rewind");
622 REG_KEY(
"TV Playback",
"NEXTSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
623 "Next Video Source"),
"Y");
624 REG_KEY(
"TV Playback",
"PREVSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
625 "Previous Video Source"),
"");
626 REG_KEY(
"TV Playback",
"NEXTINPUT", QT_TRANSLATE_NOOP(
"MythControls",
628 REG_KEY(
"TV Playback",
"NEXTCARD", QT_TRANSLATE_NOOP(
"MythControls",
630 REG_KEY(
"TV Playback",
"SKIPCOMMERCIAL", QT_TRANSLATE_NOOP(
"MythControls",
631 "Skip Commercial"),
"Z,End,Media Next");
632 REG_KEY(
"TV Playback",
"SKIPCOMMBACK", QT_TRANSLATE_NOOP(
"MythControls",
633 "Skip Commercial (Reverse)"),
"Q,Home,Media Previous");
635 "Jump to the start of the recording."),
"Ctrl+A");
636 REG_KEY(
"TV Playback",
"TOGGLEBROWSE", QT_TRANSLATE_NOOP(
"MythControls",
637 "Toggle channel browse mode"),
"O");
639 "Toggle recording status of current program"),
"R");
641 "Toggle the current channel as a favorite"),
"?");
643 "Volume down"),
"[,{,F10,Volume Down");
645 "Volume up"),
"],},F11,Volume Up");
647 "Mute"),
"|,\\,F9,Volume Mute");
649 "Set the volume"),
"");
650 REG_KEY(
"TV Playback",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
651 "Cycle audio channels"),
"");
653 "Toggle audio upmixer"),
"Ctrl+U");
655 QT_TRANSLATE_NOOP(
"MythControls",
"Move BottomLine off screen"),
"L");
657 QT_TRANSLATE_NOOP(
"MythControls",
"Save manual zoom for BottomLine"),
"");
658 REG_KEY(
"TV Playback",
"TOGGLEASPECT", QT_TRANSLATE_NOOP(
"MythControls",
659 "Toggle the video aspect ratio"),
"Ctrl+W");
660 REG_KEY(
"TV Playback",
"TOGGLEFILL", QT_TRANSLATE_NOOP(
"MythControls",
661 "Next Preconfigured Zoom mode"),
"W");
663 "Toggle any captions"),
"T");
665 "Enable any captions"),
"");
667 "Disable any captions"),
"");
668 REG_KEY(
"TV Playback",
"TOGGLETTC", QT_TRANSLATE_NOOP(
"MythControls",
669 "Toggle Teletext Captions"),
"");
670 REG_KEY(
"TV Playback",
"TOGGLESUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
671 "Toggle Subtitles"),
"");
672 REG_KEY(
"TV Playback",
"TOGGLECC608", QT_TRANSLATE_NOOP(
"MythControls",
673 "Toggle VBI CC"),
"");
674 REG_KEY(
"TV Playback",
"TOGGLECC708", QT_TRANSLATE_NOOP(
"MythControls",
675 "Toggle ATSC CC"),
"");
676 REG_KEY(
"TV Playback",
"TOGGLETTM", QT_TRANSLATE_NOOP(
"MythControls",
677 "Toggle Teletext Menu"),
"");
679 "Toggle External Subtitles"),
"");
681 "Enable External Subtitles"),
"");
683 "Disable External Subtitles"),
"");
684 REG_KEY(
"TV Playback",
"TOGGLERAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
685 "Toggle Text Subtitles"),
"");
687 REG_KEY(
"TV Playback",
"SELECTAUDIO_0", QT_TRANSLATE_NOOP(
"MythControls",
688 "Play audio track 1"),
"");
689 REG_KEY(
"TV Playback",
"SELECTAUDIO_1", QT_TRANSLATE_NOOP(
"MythControls",
690 "Play audio track 2"),
"");
691 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_0",QT_TRANSLATE_NOOP(
"MythControls",
692 "Display subtitle 1"),
"");
693 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_1",QT_TRANSLATE_NOOP(
"MythControls",
694 "Display subtitle 2"),
"");
695 REG_KEY(
"TV Playback",
"SELECTRAWTEXT_0",QT_TRANSLATE_NOOP(
"MythControls",
696 "Display Text Subtitle 1"),
"");
697 REG_KEY(
"TV Playback",
"SELECTCC608_0", QT_TRANSLATE_NOOP(
"MythControls",
698 "Display VBI CC1"),
"");
699 REG_KEY(
"TV Playback",
"SELECTCC608_1", QT_TRANSLATE_NOOP(
"MythControls",
700 "Display VBI CC2"),
"");
701 REG_KEY(
"TV Playback",
"SELECTCC608_2", QT_TRANSLATE_NOOP(
"MythControls",
702 "Display VBI CC3"),
"");
703 REG_KEY(
"TV Playback",
"SELECTCC608_3", QT_TRANSLATE_NOOP(
"MythControls",
704 "Display VBI CC4"),
"");
705 REG_KEY(
"TV Playback",
"SELECTCC708_0", QT_TRANSLATE_NOOP(
"MythControls",
706 "Display ATSC CC1"),
"");
707 REG_KEY(
"TV Playback",
"SELECTCC708_1", QT_TRANSLATE_NOOP(
"MythControls",
708 "Display ATSC CC2"),
"");
709 REG_KEY(
"TV Playback",
"SELECTCC708_2", QT_TRANSLATE_NOOP(
"MythControls",
710 "Display ATSC CC3"),
"");
711 REG_KEY(
"TV Playback",
"SELECTCC708_3", QT_TRANSLATE_NOOP(
"MythControls",
712 "Display ATSC CC4"),
"");
714 "Enable Forced Subtitles"),
"");
716 "Disable Forced Subtitles"),
"");
718 REG_KEY(
"TV Playback",
"NEXTAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
719 "Next audio track"),
"+");
720 REG_KEY(
"TV Playback",
"PREVAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
721 "Previous audio track"),
"-");
722 REG_KEY(
"TV Playback",
"NEXTSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
723 "Next subtitle track"),
"");
724 REG_KEY(
"TV Playback",
"PREVSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
725 "Previous subtitle track"),
"");
726 REG_KEY(
"TV Playback",
"NEXTRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
727 "Next Text track"),
"");
728 REG_KEY(
"TV Playback",
"PREVRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
729 "Previous Text track"),
"");
730 REG_KEY(
"TV Playback",
"NEXTCC608", QT_TRANSLATE_NOOP(
"MythControls",
731 "Next VBI CC track"),
"");
732 REG_KEY(
"TV Playback",
"PREVCC608", QT_TRANSLATE_NOOP(
"MythControls",
733 "Previous VBI CC track"),
"");
734 REG_KEY(
"TV Playback",
"NEXTCC708", QT_TRANSLATE_NOOP(
"MythControls",
735 "Next ATSC CC track"),
"");
736 REG_KEY(
"TV Playback",
"PREVCC708", QT_TRANSLATE_NOOP(
"MythControls",
737 "Previous ATSC CC track"),
"");
738 REG_KEY(
"TV Playback",
"NEXTCC", QT_TRANSLATE_NOOP(
"MythControls",
739 "Next of any captions"),
"");
741 REG_KEY(
"TV Playback",
"NEXTSCAN", QT_TRANSLATE_NOOP(
"MythControls",
742 "Next video scan overidemode"),
"");
743 REG_KEY(
"TV Playback",
"QUEUETRANSCODE", QT_TRANSLATE_NOOP(
"MythControls",
744 "Queue the current recording for transcoding"),
"X");
745 REG_KEY(
"TV Playback",
"SPEEDINC", QT_TRANSLATE_NOOP(
"MythControls",
746 "Increase the playback speed"),
"U");
747 REG_KEY(
"TV Playback",
"SPEEDDEC", QT_TRANSLATE_NOOP(
"MythControls",
748 "Decrease the playback speed"),
"J");
749 REG_KEY(
"TV Playback",
"ADJUSTSTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
750 "Turn on time stretch control"),
"A");
751 REG_KEY(
"TV Playback",
"STRETCHINC", QT_TRANSLATE_NOOP(
"MythControls",
752 "Increase time stretch speed"),
"");
753 REG_KEY(
"TV Playback",
"STRETCHDEC", QT_TRANSLATE_NOOP(
"MythControls",
754 "Decrease time stretch speed"),
"");
755 REG_KEY(
"TV Playback",
"TOGGLESTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
756 "Toggle time stretch speed"),
"");
758 QT_TRANSLATE_NOOP(
"MythControls",
759 "Turn on audio sync adjustment controls"),
"");
761 QT_TRANSLATE_NOOP(
"MythControls",
762 "Set the audio sync adjustment"),
"");
763 REG_KEY(
"TV Playback",
"TOGGLEPICCONTROLS",
764 QT_TRANSLATE_NOOP(
"MythControls",
"Playback picture adjustments"),
767 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture brightness"),
"");
769 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture contrast"),
"");
771 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture color"),
"");
773 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture hue"),
"");
775 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
776 "for this channel"),
"Ctrl+G");
778 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
779 "for this recorder"),
"G");
780 REG_KEY(
"TV Playback",
"CYCLECOMMSKIPMODE",
781 QT_TRANSLATE_NOOP(
"MythControls",
"Cycle Commercial Skip mode"),
784 "Show the Program Guide"),
"S");
786 "Show the Program Finder"),
"#");
788 "Toggle the Sleep Timer"),
"F8");
792 "Jump to previously played recording"),
"");
794 "Display menu of recorded programs to jump to"),
"");
796 "Display scheduled recording list"),
"");
798 "Display previously recorded episodes"),
"");
800 "Monitor Signal Quality"),
"Alt+F7");
802 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Root Menu"),
"");
804 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the Popup Menu"),
"");
806 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Chapter Menu"),
"");
808 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Title Menu"),
"");
810 QT_TRANSLATE_NOOP(
"MythControls",
"Exit Show without any prompts"),
813 "Jump to a chapter"),
"");
815 "Switch title"),
"");
817 "Switch angle"),
"");
819 "OSD Navigation"),
"");
821 "Zoom mode - shift up"),
"");
823 "Zoom mode - shift down"),
"");
825 "Zoom mode - shift left"),
"");
827 "Zoom mode - shift right"),
"");
829 QT_TRANSLATE_NOOP(
"MythControls",
830 "Zoom mode - increase aspect ratio"),
"3");
832 QT_TRANSLATE_NOOP(
"MythControls",
833 "Zoom mode - decrease aspect ratio"),
"7");
835 "Zoom mode - zoom in"),
"9");
837 "Zoom mode - zoom out"),
"1");
839 QT_TRANSLATE_NOOP(
"MythControls",
840 "Zoom mode - vertical zoom in"),
"8");
842 QT_TRANSLATE_NOOP(
"MythControls",
843 "Zoom mode - vertical zoom out"),
"2");
845 QT_TRANSLATE_NOOP(
"MythControls",
846 "Zoom mode - horizontal zoom in"),
"6");
848 QT_TRANSLATE_NOOP(
"MythControls",
849 "Zoom mode - horizontal zoom out"),
"4");
851 "Zoom mode - quit and abandon changes"),
"");
853 "Zoom mode - commit changes"),
"");
856 "Display list of cast members"),
"");
862 "Menu Green"),
"F3");
864 "Menu Yellow"),
"F4");
876 "Clear editing cut points"),
"C,Q,Home");
878 "Invert Begin/End cut points"),
"I,Home Page");
882 "Load cuts from detected commercials"),
"Z,End");
884 "Jump to the next cut point"),
"PgDown,Media Next");
886 "Jump to the previous cut point"),
"PgUp,Media Previous");
888 "Jump back 10x the normal amount"),
",,<,Ctrl+B,Media Rewind");
890 "Jump forward 10x the normal amount"),
">,.,Ctrl+F,Media Fast Forward");
892 "Cut point editor compact menu"),
"Alt+M");
896 "Next Page"),
"Down");
898 "Previous Page"),
"Up");
900 "Next Subpage"),
"Right");
902 "Previous Subpage"),
"Left");
904 "Toggle Teletext"),
"T");
908 "Menu Green"),
"F3");
910 "Menu Yellow"),
"F4");
914 "Menu White"),
"F6");
916 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle Background"),
"F7");
918 "Reveal hidden Text"),
"F8");
922 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle audio visualisation"),
"");
926 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle OSD playback information"),
"");
930 QT_TRANSLATE_NOOP(
"MythControls",
"Auto 3D"),
"");
932 QT_TRANSLATE_NOOP(
"MythControls",
"Ignore 3D"),
"");
934 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Side by Side"),
"");
936 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Top and Bottom"),
"");
990 { tr(
"Off",
"Sleep timer"), 0min },
991 { tr(
"30m",
"Sleep timer"), 30min },
992 { tr(
"1h",
"Sleep timer"), 60min },
993 { tr(
"1h30m",
"Sleep timer"), 90min },
994 { tr(
"2h",
"Sleep timer"), 120min }
1011 m_mainWindow(MainWindow),
1015 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Creating TV object");
1017 QObject::setObjectName(
"TV");
1034 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Finished creating TV object");
1039 QMap<QString,QString> kv;
1040 kv[
"LiveTVIdleTimeout"] =
"0";
1041 kv[
"BrowseMaxForward"] =
"240";
1042 kv[
"PlaybackExitPrompt"] =
"0";
1043 kv[
"AutomaticSetWatched"] =
"0";
1044 kv[
"EndOfRecordingExitPrompt"] =
"0";
1045 kv[
"JumpToProgramOSD"] =
"1";
1046 kv[
"GuiSizeForTV"] =
"0";
1047 kv[
"UseVideoModes"] =
"0";
1048 kv[
"JobsRunOnRecordHost"] =
"0";
1049 kv[
"ContinueEmbeddedTVPlay"] =
"0";
1050 kv[
"UseFixedWindowSize"] =
"1";
1051 kv[
"RunFrontendInWindow"] =
"0";
1052 kv[
"PersistentBrowseMode"] =
"0";
1053 kv[
"BrowseAllTuners"] =
"0";
1054 kv[
"ChannelOrdering"] =
"channum";
1056 kv[
"CustomFilters"] =
"";
1057 kv[
"ChannelFormat"] =
"<num> <sign>";
1059 kv[
"TryUnflaggedSkip"] =
"0";
1061 kv[
"ChannelGroupDefault"] =
"-1";
1062 kv[
"BrowseChannelGroup"] =
"0";
1063 kv[
"SmartForward"] =
"0";
1064 kv[
"FFRewReposTime"] =
"100";
1065 kv[
"FFRewReverse"] =
"1";
1067 kv[
"BrowseChannelGroup"] =
"0";
1068 kv[
"ChannelGroupDefault"] =
"-1";
1069 kv[
"ChannelGroupRememberLast"] =
"0";
1071 kv[
"VbiFormat"] =
"";
1072 kv[
"DecodeVBIFormat"] =
"";
1075 kv[
"PlaybackScreenPressKeyMap"] =
"P,Up,Z,],Left,Return,Return,Right,A,Down,Q,[";
1076 kv[
"LiveTVScreenPressKeyMap"] =
"P,Up,Z,S,Left,Return,Return,Right,A,Down,Q,F";
1078 constexpr std::array<const int,8> ff_rew_def { 3, 5, 10, 20, 30, 60, 120, 180 };
1079 for (
size_t i = 0; i < ff_rew_def.size(); i++)
1080 kv[QString(
"FFRewSpeed%1").arg(i)] = QString::number(ff_rew_def[i]);
1087 QString db_channel_ordering;
1089 m_dbIdleTimeout = std::chrono::minutes(kv[
"LiveTVIdleTimeout"].toUInt());
1090 auto db_browse_max_forward = std::chrono::minutes(kv[
"BrowseMaxForward"].toUInt());
1101 db_channel_ordering = kv[
"ChannelOrdering"];
1111 QString beVBI = kv[
"VbiFormat"];
1112 QString feVBI = kv[
"DecodeVBIFormat"];
1129 for (
size_t i = 0; i <
sizeof(ff_rew_def)/
sizeof(ff_rew_def[0]); i++)
1130 m_ffRewSpeeds.push_back(kv[QString(
"FFRewSpeed%1").arg(i)].toInt());
1147 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1151 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No MythMainWindow");
1172 fullscreen |= (0 == gui_width && 0 == gui_height);
1187 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created TvPlayWindow.");
1198 QCoreApplication::processEvents();
1223 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1229 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1250 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"-- lock");
1283 lcd->setFunctionLEDs(
FUNC_TV,
false);
1285 lcd->switchToTime();
1301 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1311 QCoreApplication::processEvents();
1387 .toUTC().toString(
"yyyy-MM-ddThh:mm:ssZ"));
1398 if (!
info.text[
"totalchapters"].isEmpty())
1400 QList<std::chrono::seconds> chapters;
1403 for (std::chrono::seconds chapter : std::as_const(chapters))
1404 var << QVariant((
long long)chapter.count());
1405 status.insert(
"chaptertimes", var);
1412 int currenttrack = -1;
1415 for (
int i = 0; i < list.size(); i++)
1417 if (i == currenttrack)
1418 status.insert(
"currentsubtitletrack", list[i]);
1419 tracks.insert(
"SELECTSUBTITLE_" + QString::number(i), list[i]);
1426 for (
int i = 0; i < list.size(); i++)
1428 if (i == currenttrack)
1429 status.insert(
"currentsubtitletrack", list[i]);
1430 tracks.insert(
"SELECTTTC_" + QString::number(i), list[i]);
1437 for (
int i = 0; i < list.size(); i++)
1439 if (i == currenttrack)
1440 status.insert(
"currentsubtitletrack", list[i]);
1441 tracks.insert(
"SELECTCC708_" + QString::number(i), list[i]);
1448 for (
int i = 0; i < list.size(); i++)
1450 if (i == currenttrack)
1451 status.insert(
"currentsubtitletrack", list[i]);
1452 tracks.insert(
"SELECTCC608_" + QString::number(i), list[i]);
1459 for (
int i = 0; i < list.size(); i++)
1461 if (i == currenttrack)
1462 status.insert(
"currentsubtitletrack", list[i]);
1463 tracks.insert(
"SELECTRAWTEXT_" + QString::number(i), list[i]);
1469 status.insert(
"currentsubtitletrack", tr(
"External Subtitles"));
1473 status.insert(
"totalsubtitletracks", tracks.size());
1474 if (!tracks.isEmpty())
1475 status.insert(
"subtitletracks", tracks);
1480 for (
int i = 0; i < list.size(); i++)
1482 if (i == currenttrack)
1483 status.insert(
"currentaudiotrack", list[i]);
1484 tracks.insert(
"SELECTAUDIO_" + QString::number(i), list[i]);
1487 status.insert(
"totalaudiotracks", tracks.size());
1488 if (!tracks.isEmpty())
1489 status.insert(
"audiotracks", tracks);
1513 for (
auto tit =
info.text.cbegin(); tit !=
info.text.cend(); ++tit)
1514 status.insert(tit.key(), tit.value());
1516 QHashIterator<QString,int> vit(
info.values);
1517 while (vit.hasNext())
1520 status.insert(vit.key(), vit.value());
1548 LOG(VB_GENERAL, LOG_INFO, QString(
"Using Idle Timer. %1 minutes")
1570 else if (!Selection.empty())
1572 for (
const auto & ci : Selection)
1574 uint chanid = ci.m_chanId;
1575 QString channum = ci.m_chanNum;
1576 if (!chanid || channum.isEmpty())
1580 if (chanid && !channum.isEmpty() && !cards.isEmpty())
1618 if (!
info->GetChanID())
1625 QString key =
info->MakeUniqueKey();
1630 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"AskAllowRecording -- " +
1631 QString(
"adding '%1'").arg(
info->m_title));
1639 LOG(VB_GENERAL, LOG_INFO,
LOC +
"-- " +
1640 QString(
"removing '%1'").arg(
info->GetTitle()));
1644 delete (*it).m_info;
1661 QString single_rec = tr(
"MythTV wants to record \"%1\" on %2 in %d seconds. Do you want to:");
1663 QString record_watch = tr(
"Record and watch while it records");
1664 QString let_record1 = tr(
"Let it record and go back to the Main Menu");
1665 QString let_recordm = tr(
"Let them record and go back to the Main Menu");
1666 QString record_later1 = tr(
"Record it later, I want to watch TV");
1667 QString record_laterm = tr(
"Record them later, I want to watch TV");
1668 QString do_not_record1= tr(
"Don't let it record, I want to watch TV");
1669 QString do_not_recordm= tr(
"Don't let them record, I want to watch TV");
1676 if ((*it).m_expiry <= timeNow)
1679 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"-- " +
1680 QString(
"removing '%1'").arg((*it).m_info->m_title));
1682 delete (*it).m_info;
1690 std::chrono::milliseconds timeuntil = 0ms;
1697 (*it).m_isInSameInputGroup = (*it).m_isConflicting =
true;
1702 bool busy_input_grps_loaded =
false;
1703 std::vector<uint> busy_input_grps;
1710 (*it).m_isInSameInputGroup =
1711 (cardid == (*it).m_info->GetInputID());
1713 if ((*it).m_isInSameInputGroup)
1717 if (!busy_input_grps_loaded)
1720 busy_input_grps_loaded =
true;
1723 std::vector<uint> input_grps =
1726 for (
uint grp : input_grps)
1728 if (
find(busy_input_grps.begin(), busy_input_grps.end(),
1729 grp) != busy_input_grps.end())
1731 (*it).m_isInSameInputGroup =
true;
1741 if (!(*it).m_isInSameInputGroup)
1742 (*it).m_isConflicting =
false;
1743 else if (cardid == (*it).m_info->GetInputID())
1744 (*it).m_isConflicting =
true;
1746 (*it).m_isConflicting =
true;
1748 (busy_input.
m_mplexId == (*it).m_info->QueryMplexID())) ||
1750 (busy_input.
m_chanId == (*it).m_info->GetChanID())))
1751 (*it).m_isConflicting =
false;
1753 (*it).m_isConflicting =
true;
1755 conflict_count += (*it).m_isConflicting ? 1 : 0;
1762 if (conflict_count == 0)
1764 LOG(VB_GENERAL, LOG_INFO,
LOC +
"The scheduler wants to make "
1765 "a non-conflicting recording.");
1769 else if (conflict_count == 1 && ((*it).m_info->GetInputID() == cardid))
1772 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"UpdateOSDAskAllowDialog -- " +
1780 .replace(
"<num>", (*it).m_info->GetChanNum())
1781 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1782 .replace(
"<name>", (*it).m_info->GetChannelName());
1784 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1789 dialog.m_buttons.push_back({ record_watch,
"DIALOG_ASKALLOW_WATCH_0",
false, !((*it).m_hasRec)} );
1790 dialog.m_buttons.push_back({ let_record1,
"DIALOG_ASKALLOW_EXIT_0" });
1791 dialog.m_buttons.push_back({ ((*it).m_hasLater) ? record_later1 : do_not_record1,
1792 "DIALOG_ASKALLOW_CANCELRECORDING_0",
false, ((*it).m_hasRec) });
1797 if (conflict_count > 1)
1800 "MythTV wants to record these programs in %d seconds:");
1804 bool has_rec =
false;
1807 if (!(*it).m_isConflicting)
1810 QString title = (*it).m_info->GetTitle();
1811 if ((title.length() < 10) && !(*it).m_info->GetSubtitle().isEmpty())
1812 title +=
": " + (*it).m_info->GetSubtitle();
1813 if (title.length() > 20)
1814 title = title.left(17) +
"...";
1818 .replace(
"<num>", (*it).m_info->GetChanNum())
1819 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1820 .replace(
"<name>", (*it).m_info->GetChannelName());
1822 if (conflict_count > 1)
1824 message += tr(
"\"%1\" on %2").arg(title, channel);
1829 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1830 has_rec = (*it).m_hasRec;
1834 if (conflict_count > 1)
1837 message += tr(
"Do you want to:");
1840 bool all_have_later =
true;
1841 timeuntil = 9999999ms;
1844 if ((*it).m_isConflicting)
1846 all_have_later &= (*it).m_hasLater;
1851 timeuntil = (9999999ms == timeuntil) ? 0ms : timeuntil;
1853 if (conflict_count > 1)
1857 { let_recordm,
"DIALOG_ASKALLOW_EXIT_0",
false,
true },
1858 { all_have_later ? record_laterm : do_not_recordm,
"DIALOG_ASKALLOW_CANCELCONFLICTING_0" }
1865 { let_record1,
"DIALOG_ASKALLOW_EXIT_0",
false, !has_rec},
1866 { all_have_later ? record_later1 : do_not_record1,
"DIALOG_ASKALLOW_CANCELRECORDING_0",
false, has_rec}
1879 LOG(VB_GENERAL, LOG_ERR,
"allowrecordingbox : askAllowLock is locked");
1883 if (
Action ==
"CANCELRECORDING")
1888 else if (
Action ==
"CANCELCONFLICTING")
1892 if (pgm.m_isConflicting)
1896 else if (
Action ==
"WATCH")
1962#define TRANSITION(ASTATE,BSTATE) ((ctxState == (ASTATE)) && (desiredNextState == (BSTATE)))
1964#define SET_NEXT() do { nextState = desiredNextState; changed = true; } while(false)
1965#define SET_LAST() do { nextState = ctxState; changed = true; } while(false)
1970 QByteArray msg_arr = msg.toLatin1();
1971 QString msg_i18n = TV::tr(msg_arr.constData());
1972 QByteArray msg_i18n_arr = msg_i18n.toLatin1();
1973 return (msg_arr == msg_i18n_arr) ? msg_i18n : msg;
1988 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Called after fatal error detected.");
1992 bool changed =
false;
1998 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning, called with no state to change to.");
2006 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Attempting to change from %1 to %2")
2011 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to set to an error state!");
2036 QString channum =
"";
2040 QStringList reclist;
2043 query.
prepare(
"SELECT channum FROM channel "
2044 "WHERE chanid = :CHANID");
2047 channum = query.
value(0).toString();
2049 channum = QString::number(chanid);
2052 QString::number(chanid));
2057 if (!reclist.empty())
2076 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- begin");
2078 if (chanid && !channum.isEmpty())
2083 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- end");
2087 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2101 LOG(VB_GENERAL, LOG_INFO,
LOC +
2102 QString(
"playbackURL(%1) inputtype(%2)")
2107 playbackURL,
false,
true,
2121 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2176 LOG(VB_GENERAL, LOG_ERR,
LOC +
2177 "Couldn't find recorder for in-progress recording");
2196 QString message =
"COMMFLAG_REQUEST ";
2211 TV::tr(
"TV Player" ),
2238 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unknown state transition: %1 to %2")
2243 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Changing from %1 to %2")
2254 LOG(VB_GENERAL, LOG_INFO,
LOC +
"State is LiveTV");
2256 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateOSDInput done");
2258 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateLCD done");
2260 LOG(VB_GENERAL, LOG_INFO,
LOC +
"ITVRestart done");
2266 QString msg = tr(
"%1 Settings")
2319 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Main UI disabled.");
2322 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
" -- end");
2337 MaxWait = (MaxWait <= 0ms) ? 40s : MaxWait;
2340 bool recording =
false;
2344 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid Remote Encoder");
2352 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Lost contact with backend");
2356 std::this_thread::sleep_for(5us);
2362 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Timed out waiting for recorder to start");
2366 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Took %1 ms to start recorder.")
2367 .arg(
t.elapsed().count()));
2386 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
2400 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stopping ring buffer");
2411 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"stopping recorder");
2416 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
2421 const int timer_id =
Event->timerId();
2429 bool handled =
true;
2490 if (!netCmd.isEmpty())
2516 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Last Program File does not exist");
2635 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Unknown timer: %1").arg(timer_id));
2645 QString lcd_time_string;
2646 bool showProgress =
true;
2663 lcd_time_string =
info.text[
"playedtime"] +
" / " +
info.text[
"totaltime"];
2665 if (lcd_time_string.length() > lcd->
getLCDWidth())
2666 lcd_time_string.remove(
' ');
2696 int timer = startTimer(Interval);
2698 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to start timer on line %1 of %2").arg(Line).arg(__FILE__));
2715 auto StateChange = [&]()
2733 QTimer::singleShot(0,
this, StateChange);
2738 auto InputChange = [&]()
2750 QTimer::singleShot(0,
this, InputChange);
2762 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Switching to program: %1")
2832 bool is_playing =
false;
2917 bool restartTimer =
false;
2923 restartTimer =
true;
2927 LOG(VB_CHANNEL, LOG_INFO,
"REC_PROGRAM -- channel change");
2993 if ((
Event->type() == QEvent::Resize))
2999 if ( (QEvent::KeyPress ==
Event->type() || QEvent::KeyRelease ==
Event->type())
3001 return TVPlaybackState::eventFilter(Object,
Event);
3003 QScopedPointer<QEvent> sNewEvent(
nullptr);
3007 if (QEvent::KeyPress ==
Event->type())
3022 switch (
Event->type())
3025 case QEvent::UpdateRequest:
3029 return TVPlaybackState::eventFilter(Object,
Event);
3032 return TVPlaybackState::eventFilter(Object,
Event);
3039 if (
Event ==
nullptr)
3040 return TVPlaybackState::event(
Event);
3042 if (QEvent::Resize ==
Event->type())
3047 const auto *qre =
dynamic_cast<const QResizeEvent*
>(
Event);
3050 return TVPlaybackState::event(
Event);
3059 if (QEvent::KeyPress ==
Event->type())
3061 const auto * ke =
dynamic_cast<QKeyEvent*
>(
Event);
3064 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"keypress: %1 '%2'")
3065 .arg(ke->key()).arg(ke->text()));
3073 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"mythgesture: g:%1 pos:%2,%3 b:%4")
3074 .arg(ge->GetGesture()).arg(ge->GetPosition().x())
3075 .arg(ge->GetPosition().y()).arg(ge->GetButton()));
3079 bool handled =
false;
3088 switch (
Event->type())
3091 case QEvent::UpdateRequest:
3101 return QObject::event(
Event);
3106 bool handled =
true;
3161 else if (
Action.startsWith(
"TOGGLE"))
3171 else if (
Action.startsWith(
"SELECT"))
3180 else if (
Action.startsWith(
"NEXT") ||
Action.startsWith(
"PREV"))
3182 int dir = (
Action.startsWith(
"NEXT")) ? +1 : -1;
3186 else if (
Action.endsWith(
"CC"))
3211 QStringList::const_iterator it;
3212 for (it = actions.begin(); it != actions.end(); ++it)
3214 if ((*it).startsWith(
"SYSEVENT") ||
3227 QList<QKeyEvent*> keyPressList;
3229 QStringList stringKeyList = KeyList.split(
',');
3230 for (
const auto & str : std::as_const(stringKeyList))
3232 QKeySequence keySequence(str);
3233 for (i = 0; i < keySequence.count(); i++)
3235#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3236 int keynum = keySequence[i];
3237 int keyCode = keynum & ~Qt::KeyboardModifierMask;
3238 auto modifiers =
static_cast<Qt::KeyboardModifiers
>(keynum & Qt::KeyboardModifierMask);
3240 int keyCode = keySequence[i].key();
3241 Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
3243 auto * keyEvent =
new QKeyEvent(QEvent::None, keyCode, modifiers);
3244 keyPressList.append(keyEvent);
3252 auto * keyEvent =
new QKeyEvent(QEvent::None, Qt::Key_Escape, Qt::NoModifier);
3253 keyPressList.append(keyEvent);
3256 return keyPressList;
3260 QStringList &Actions,
bool IsLiveTV)
3262 if (
Event && Context ==
"TV Playback")
3269 (
Event->GetButton() == Qt::LeftButton))
3273 QPoint pos =
Event->GetPosition();
3275 const int widthDivider = 4;
3276 int w4 = size.width() / widthDivider;
3277 region = pos.x() / w4;
3278 int h3 = size.height() / 3;
3279 region += (pos.y() / h3) * widthDivider;
3291 QStringList &Actions,
bool IsLiveTV,
bool AllowJumps)
3295 if (QEvent::KeyPress ==
Event->type())
3305 if (
Event ==
nullptr)
3311 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"ignoreKeys: %1").arg(ignoreKeys));
3322 auto* eKeyEvent =
dynamic_cast<QKeyEvent*
>(
Event);
3324 if (eKeyEvent->key() <= 0)
3327 switch(eKeyEvent->nativeScanCode())
3330 keycode = Qt::Key_MediaPause;
3338 auto *key =
new QKeyEvent(QEvent::KeyPress, keycode, eKeyEvent->modifiers());
3339 QCoreApplication::postEvent(
this, key);
3345 QStringList actions;
3346 bool handled =
false;
3347 bool alreadyTranslatedPlayback =
false;
3355 alreadyTranslatedPlayback =
true;
3357 if (handled || actions.isEmpty())
3360 bool esc =
IsActionable({
"ESCAPE",
"BACK" }, actions);
3371 if (QEvent::KeyPress ==
Event->type())
3373 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3431 if (QEvent::KeyPress ==
Event->type())
3433 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3436 const QString txt = qke->text();
3440 (void)txt.toInt(&ok, 16);
3441 if (ok || txt==
"_" || txt==
"-" || txt==
"#" || txt==
".")
3452 QStringList tt_actions;
3455 if (!handled && !tt_actions.isEmpty())
3457 for (
const QString&
action : std::as_const(tt_actions))
3469 if (!alreadyTranslatedPlayback)
3472 alreadyTranslatedPlayback =
true;
3475 if (!handled && !actions.isEmpty())
3477 for (
const QString&
action : std::as_const(actions))
3486 if (!alreadyTranslatedPlayback)
3489 if (handled || actions.isEmpty())
3497 if (QEvent::KeyPress ==
Event->type())
3513 for (
int i = 0; i < actions.size(); ++i)
3514 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"handled(%1) actions[%2](%3)")
3515 .arg(handled).arg(i).arg(actions[i]));
3523 for (
int i = 0; i < actions.size() && !handled; i++)
3525 const QString&
action = actions[i];
3527 int val =
action.toInt(&ok);
3545 bool handled =
true;
3566 for (
const auto&
action : std::as_const(Actions))
3577 static const QStringList passthrough =
3580 ACTION_MUTEAUDIO,
"CYCLEAUDIOCHAN",
"BOTTOMLINEMOVE",
"BOTTOMLINESAVE",
"TOGGLEASPECT"
3590 bool endmanualzoom =
false;
3591 bool handled =
true;
3592 bool updateOSD =
true;
3621 endmanualzoom =
true;
3625 endmanualzoom =
true;
3632 static const QStringList passthrough =
3640 QString msg = tr(
"Zoom Committed");
3644 msg = endmanualzoom ? tr(
"Zoom Ignored") :
3649 else if (endmanualzoom)
3696 bool handled =
true;
3721 bool handled =
true;
3744 bool handled =
true;
3767 bool handled =
true;
3802 bool IsDVD,
bool IsDVDStillFrame)
3804 bool handled =
true;
3808 else if (
IsActionable(
"SKIPCOMMBACK", Actions) && !IsDVD)
3810 else if (
IsActionable(
"QUEUETRANSCODE", Actions) && !IsDVD)
3812 else if (
IsActionable(
"QUEUETRANSCODE_AUTO", Actions) && !IsDVD)
3814 else if (
IsActionable(
"QUEUETRANSCODE_HIGH", Actions) && !IsDVD)
3816 else if (
IsActionable(
"QUEUETRANSCODE_MEDIUM", Actions) && !IsDVD)
3818 else if (
IsActionable(
"QUEUETRANSCODE_LOW", Actions) && !IsDVD)
3824 else if (
IsActionable(
"SPEEDINC", Actions) && !IsDVDStillFrame)
3826 else if (
IsActionable(
"SPEEDDEC", Actions) && !IsDVDStillFrame)
3830 else if (
IsActionable(
"CYCLECOMMSKIPMODE",Actions) && !IsDVD)
3890 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
3916 std::chrono::milliseconds rate =
m_sigMonMode ? 0ms : 100ms;
3951 bool visible =
false;
4041 else if (
IsActionable({
"INFO",
"INFOWITHCUTLIST" }, Actions))
4062 for (
auto it = Actions.cbegin(); it != Actions.cend() && !handled; ++it)
4071 bool handled =
false;
4075 for (
int i = 0; i < Actions.size() && !handled; i++)
4077 const QString&
action = Actions[i];
4079 int val =
action.toInt(&ok);
4108 bool handled =
true;
4187 info.text[
"title"] = tr(
"Position");
4195 bool handled =
true;
4217 else if (
IsActionable(
"NEXTSOURCE", Actions) && islivetv)
4221 else if (
IsActionable(
"PREVSOURCE", Actions) && islivetv)
4225 else if (
IsActionable(
"NEXTINPUT", Actions) && islivetv)
4233 else if (
IsActionable(
"PREVCHAN", Actions) && islivetv)
4306 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"(%1) ignoreKeys: %2").arg(
Command).arg(ignoreKeys));
4311 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Ignoring network control command because ignoreKeys is set");
4315 QStringList tokens =
Command.split(
" ", Qt::SkipEmptyParts);
4316 if (tokens.size() < 2)
4318 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not enough tokens in network control command " + QString(
"'%1'").arg(
Command));
4330 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4331 "Ignoring network control command\n\t\t\t" +
4332 QString(
"because dialog is waiting for a response"));
4336 if (tokens[1] !=
"QUERY")
4339 if (tokens.size() == 3 && tokens[1] ==
"CHANID")
4345 else if (tokens.size() == 3 && tokens[1] ==
"CHANNEL")
4349 static const QRegularExpression kChannelNumRE { R
"(^[-\.\d_#]+$)" };
4350 if (tokens[2] ==
"UP")
4352 else if (tokens[2] ==
"DOWN")
4354 else if (tokens[2].contains(kChannelNumRE))
4358 else if (tokens.size() == 3 && tokens[1] ==
"SPEED")
4362 if (tokens[2] ==
"0x")
4369 else if (tokens[2] ==
"normal")
4379 static const QRegularExpression kSpeedRE { R
"(^\-*(\d*\.)?\d+x$)" };
4380 float tmpSpeed = 1.0F;
4383 if (tokens[2].contains(kSpeedRE))
4385 QString speed = tokens[2].left(tokens[2].length()-1);
4386 tmpSpeed = speed.toFloat(&ok);
4390 static const QRegularExpression re { R
"(^(\-*\d+)\/(\d+)x$)" };
4391 auto match = re.match(tokens[2]);
4392 if (match.hasMatch())
4394 QStringList matches = match.capturedTexts();
4395 int numerator = matches[1].toInt(&ok);
4396 int denominator = matches[2].toInt(&ok);
4398 if (ok && denominator != 0)
4399 tmpSpeed =
static_cast<float>(numerator) /
static_cast<float>(denominator);
4407 float searchSpeed = fabs(tmpSpeed);
4412 if (tmpSpeed == 0.0F)
4420 else if (tmpSpeed == 1.0F)
4439 else if (tmpSpeed > 1)
4447 else if (0.125F <= tmpSpeed && tmpSpeed <= 2.0F)
4455 LOG(VB_GENERAL, LOG_WARNING, QString(
"Couldn't find %1 speed. Setting Speed to 1x")
4456 .arg(
static_cast<double>(searchSpeed)));
4463 LOG(VB_GENERAL, LOG_ERR, QString(
"Found an unknown speed of %1").arg(tokens[2]));
4467 else if (tokens.size() == 2 && tokens[1] ==
"STOP")
4474 static const QRegularExpression kDigitsRE {
"^\\d+$" };
4478 if (tokens[2] ==
"BEGINNING")
4480 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
4482 else if (tokens[2] ==
"FORWARD")
4486 else if (tokens[2] ==
"BACKWARD")
4490 else if ((tokens[2] ==
"POSITION" ||
4491 tokens[2] ==
"POSITIONWITHCUTLIST") &&
4492 (tokens.size() == 4) &&
4493 (tokens[3].contains(kDigitsRE)))
4495 DoSeekAbsolute(tokens[3].toInt(), tokens[2] ==
"POSITIONWITHCUTLIST");
4498 else if (tokens.size() >= 3 && tokens[1] ==
"SUBTITLES")
4501 uint track = tokens[2].toUInt(&ok);
4513 uint size =
static_cast<uint>(subs.size());
4516 if (track >=
start && track < finish)
4525 finish =
start + size;
4526 if (track >=
start && track < finish)
4535 finish =
start + size;
4536 if (track >=
start && track < finish)
4545 finish =
start + size;
4546 if (track >=
start && track < finish)
4555 finish =
start + size;
4556 if (track >=
start && track < finish)
4565 finish =
start + size;
4566 if (track >=
start && track < finish)
4574 else if (tokens.size() >= 3 && tokens[1] ==
"VOLUME")
4576 static const QRegularExpression re {
"(\\d+)%?" };
4577 auto match = re.match(tokens[2]);
4578 if (match.hasMatch())
4580 QStringList matches = match.capturedTexts();
4582 LOG(VB_GENERAL, LOG_INFO, QString(
"Set Volume to %1%").arg(matches[1]));
4585 int vol = matches[1].toInt(&ok);
4589 if (0 <= vol && vol <= 100)
4593 else if (tokens.size() >= 3 && tokens[1] ==
"QUERY")
4595 if (tokens[2] ==
"POSITION")
4610 static const QRegularExpression re {
"Play (.*)x" };
4612 if (match.hasMatch())
4614 QStringList matches = match.capturedTexts();
4615 speedStr = QString(
"%1x").arg(matches[1]);
4627 QString infoStr =
"";
4651 infoStr =
"Recorded";
4659 QString bufferFilename =
4661 if ((infoStr ==
"Recorded") || (infoStr ==
"LiveTV"))
4663 infoStr += QString(
" %1 %2 %3 %4 %5 %6 %7")
4664 .arg(
info.text[
"description"],
4669 QString::number(fplay),
4671 QString::number(rate));
4675 QString position =
info.text[
"description"].section(
" ",0,0);
4676 infoStr += QString(
" %1 %2 %3 %4 %5")
4680 QString::number(fplay),
4681 QString::number(rate));
4684 infoStr += QString(
" Subtitles:");
4689 infoStr += QString(
" *0:[None]*");
4691 infoStr += QString(
" 0:[None]");
4696 for (
int i = 0; i < subs.size(); i++)
4699 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4701 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4706 for (
int i = 0; i < subs.size(); i++)
4709 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4711 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4716 for (
int i = 0; i < subs.size(); i++)
4719 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4721 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4726 for (
int i = 0; i < subs.size(); i++)
4729 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4731 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4736 for (
int i = 0; i < subs.size(); i++)
4739 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4741 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4746 for (
int i = 0; i < subs.size(); i++)
4749 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4751 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4757 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4761 else if (tokens[2] ==
"VOLUME")
4764 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4773 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- begin").arg(
StateToString(desiredState)));
4780 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Created player."));
4785 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"Failed to create player."));
4788 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- end %2")
4894 bool paused =
false;
4916 bool ignore =
false;
4917 bool paused =
false;
4942 if (Time > -0.001F && Time < +0.001F)
4945 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1 seconds").arg(
static_cast<double>(Time)));
4966 else if (Time < 0.0F)
4978 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1").arg(FrameNum));
5004 const int kRewind = 4;
5005 const int kForward = 8;
5006 const int kSticky = 16;
5007 const int kSlippery = 32;
5008 const int kRelative = 64;
5009 const int kAbsolute = 128;
5010 const int kIgnoreCutlist = 256;
5011 const int kWhenceMask = 3;
5016 flags =
ARBSEEK_END | kForward | kSticky | kAbsolute;
5022 flags =
ARBSEEK_SET | kRewind | kSticky | kAbsolute;
5028 int direction = (flags & kRewind) ? -1 : 1;
5037 QString message = (flags & kRewind) ? tr(
"Rewind") :
5039 if (flags & kAbsolute)
5041 float time = direction;
5042 DoSeek(time, message,
true, (flags & kIgnoreCutlist) == 0);
5049 uint64_t targetRel = frameRel +
static_cast<uint64_t
>(direction);
5050 if (frameRel == 0 && direction < 0)
5054 targetRel = std::min(targetRel, maxRel);
5062 else if (flags & kSticky)
5066 else if (flags & kRewind)
5086void TV::DoSeek(
float Time,
const QString &Msg,
bool TimeIsOffset,
bool HonorCutlist)
5091 bool limitkeys =
false;
5133 DoSeek(Seconds, tr(
"Jump To"),
false, HonorCutlist);
5145 int64_t time = ((seek / 100) * 3600) + ((seek % 100) * 60);
5149 DoSeek(time, tr(
"Jump Ahead"),
true, HonorCutlist);
5153 DoSeek(-time, tr(
"Jump Back"),
true, HonorCutlist);
5166 DoSeek(std::max(0.0F, dur -
static_cast<float>(time)), tr(
"Jump To"),
false, HonorCutlist);
5300 auto index =
static_cast<size_t>(Index);
5369 QString jobHost =
"";
5374 QString msg = tr(
"Try Again");
5381 msg = tr(
"Transcoding");
5391 int num_chapters = 0;
5396 return num_chapters;
5444 int currentTitle = 0;
5449 return currentTitle;
5464 int currentAngle = 0;
5469 return currentAngle;
5484 std::chrono::seconds seconds = 0s;
5547 info.text[
"title"] = tr(
"Skip");
5548 info.text[
"description"] = tr(
"Searching");
5560 QMap<uint,InputInfo> sources;
5565 uint sourceid =
info[
"sourceid"].toUInt();
5568 for (
auto & input : inputs)
5571 if ((!sources.contains(input.m_sourceId)) ||
5572 ((cardid == input.m_inputId) && (cardid != sources[input.m_sourceId].m_inputId)))
5574 sources[input.m_sourceId] = input;
5579 QMap<uint,InputInfo>::const_iterator beg = sources.constFind(sourceid);
5580 QMap<uint,InputInfo>::const_iterator sit = beg;
5582 if (sit == sources.constEnd())
5588 if (sit == sources.constEnd())
5589 sit = sources.constBegin();
5594 if (sit != sources.constBegin())
5598 QMap<uint,InputInfo>::const_iterator
tmp = sources.constBegin();
5599 while (
tmp != sources.constEnd())
5626 QCoreApplication::processEvents();
5628 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1,'%2',%3)").arg(ChanID).arg(ChanNum).arg(InputID));
5635 QStringList reclist;
5638 reclist.push_back(QString::number(InputID));
5640 else if (ChanID || !ChanNum.isEmpty())
5647 if (!reclist.empty())
5655 if (ChanID && ChanNum.isEmpty())
5658 if (!ChanNum.isEmpty())
5701 if (ChanNum.isEmpty() && ChanID)
5703 if (ChanNum.isEmpty() && InputID)
5709 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully restarted");
5722 playbackURL,
false,
true,
5749 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
5763 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No recorder to switch to...");
5777 LOG(VB_GENERAL, LOG_ERR,
"TV::ToggleChannelFavorite() -- currently disabled");
5845 bool commitSmart =
false;
5857 inputStr = inputStr.isEmpty() ?
"?" : inputStr;
5861 inputStr = entryStr +
" " + inputStr;
5865 inputStr = tr(
"Seek:",
"seek to location") +
" " + inputStr;
5875static QString
add_spacer(
const QString &chan,
const QString &spacer)
5877 if ((chan.length() >= 2) && !spacer.isEmpty())
5878 return chan.left(chan.length()-1) + spacer + chan.right(1);
5890#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
5891 int size = chan.size();
5893 qsizetype size = chan.size();
5895 if ((size > 2) && (chan.at(size - 1) == chan.at(size - 2)))
5898 chan.right(1).toUInt(&ok);
5901 chan = chan.left(chan.length()-1);
5909 QString needed_spacer;
5910 uint pref_cardid = 0;
5911 bool is_not_complete =
true;
5913 bool valid_prefix =
false;
5917 chan, pref_cardid, is_not_complete, needed_spacer);
5920#if DEBUG_CHANNEL_PREFIX
5921 LOG(VB_GENERAL, LOG_DEBUG, QString(
"valid_pref(%1) cardid(%2) chan(%3) "
5922 "pref_cardid(%4) complete(%5) sp(%6)")
5923 .arg(valid_prefix).arg(0).arg(chan)
5924 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5932 else if (!needed_spacer.isEmpty())
5938#if DEBUG_CHANNEL_PREFIX
5939 LOG(VB_GENERAL, LOG_DEBUG, QString(
" ValidPref(%1) CardId(%2) Chan(%3) "
5940 " PrefCardId(%4) Complete(%5) Sp(%6)")
5942 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5949 return !is_not_complete;
5954 bool commited =
false;
5956 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
5957 QString(
"livetv(%1) qchannum(%2) qchanid(%3)")
5987 if (channum.isEmpty())
6010 uint old_chanid = 0;
6016 LOG(VB_GENERAL, LOG_ERR,
LOC +
6017 "no active ctx playingInfo.");
6079 uint cardid,
const QString &channum)
6082 uint cur_sourceid = 0;
6095 if (cur_sourceid != sourceid && sourceid)
6102 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1, '%2')").arg(Chanid).arg(
Channum));
6108 QStringList reclist;
6109 QVector<uint> tunable_on;
6113 if (channum.isEmpty() && Chanid)
6134 QString needed_spacer;
6135 uint pref_cardid = 0;
6140 dummy, needed_spacer);
6142 LOG(VB_CHANNEL, LOG_INFO,
LOC +
6143 QString(
"CheckChannelPrefix(%1, pref_cardid %2, %3, '%4') "
6145 .arg(
Channum).arg(pref_cardid).arg(dummy).arg(needed_spacer)
6149 if (pref_cardid != cardid)
6158 getit = !tunable_on.contains(cardid);
6166 if (tunable_on.empty())
6172 for (
const auto& rec : std::as_const(
tmp))
6174 if ((Chanid == 0U) || tunable_on.contains(rec.toUInt()))
6175 reclist.push_back(rec);
6180 if (!reclist.empty())
6244 for (
const auto & option : Options)
6246 uint chanid = option.m_chanId;
6247 QString channum = option.m_chanNum;
6266 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Previous channel number '%1'").arg(channum));
6267 if (channum.isEmpty())
6277 if (!ImmediateChange)
6283 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"'%1'->'%2'")
6284 .arg(cur_channum, prev_channum));
6287 if (cur_channum != prev_channum && !prev_channum.isEmpty())
6296 if (ImmediateChange)
6310 emit
HideAll(
true,
nullptr,
true);
6328 bool hideAll =
false;
6344 else if (is_prog_info_disp && !paused)
6348 else if (IncludeStatusOSD)
6366 info.text[
"title"] = (paused ? tr(
"Paused") : tr(
"Position"));
6412 const QString& Value,
int Type,
const QString& Units,
6416 info.values.insert(
"position", Position);
6417 info.values.insert(
"relposition", Position);
6418 info.text.insert(
"title", Title);
6419 info.text.insert(
"description", Desc);
6420 info.text.insert(
"value", Value);
6421 info.text.insert(
"units", Units);
6427 LOG(VB_PLAYBACK, LOG_INFO, QString(
"UpdateOSDSeekMessage(%1, %2)").arg(Msg).arg(Timeout));
6433 info.text[
"title"] = Msg;
6468 infoMap[
"callsign"].isEmpty())
6480 SignalMonitorList::const_iterator it;
6481 for (it = slist.begin(); it != slist.end(); ++it)
6482 if (
"error" == it->GetShortName())
6483 infoMap[QString(
"error%1").arg(i++)] = it->GetName();
6485 for (it = slist.begin(); it != slist.end(); ++it)
6486 if (
"message" == it->GetShortName())
6487 infoMap[QString(
"message%1").arg(i++)] = it->GetName();
6491 uint ber = 0xffffffff;
6503 for (it = slist.begin(); it != slist.end(); ++it)
6505 if (
"error" == it->GetShortName())
6507 err = it->GetName();
6511 if (
"message" == it->GetShortName())
6513 msg = it->GetName();
6514 LOG(VB_GENERAL, LOG_INFO,
"msg: " + msg);
6518 infoMap[it->GetShortName()] = QString::number(it->GetValue());
6519 if (
"signal" == it->GetShortName())
6520 sig = it->GetNormalizedValue(0, 100);
6521 else if (
"snr" == it->GetShortName())
6522 snr = it->GetValue();
6523 else if (
"ber" == it->GetShortName())
6524 ber =
static_cast<uint>(it->GetValue());
6525 else if (
"pos" == it->GetShortName())
6526 pos = it->GetValue();
6527 else if (
"script" == it->GetShortName())
6528 tuned = it->GetValue();
6529 else if (
"seen_pat" == it->GetShortName())
6530 pat = it->IsGood() ?
"a" :
"_";
6531 else if (
"matching_pat" == it->GetShortName())
6532 pat = it->IsGood() ?
"A" : pat;
6533 else if (
"seen_pmt" == it->GetShortName())
6534 pmt = it->IsGood() ?
"m" :
"_";
6535 else if (
"matching_pmt" == it->GetShortName())
6536 pmt = it->IsGood() ?
"M" : pmt;
6537 else if (
"seen_mgt" == it->GetShortName())
6538 mgt = it->IsGood() ?
"g" :
"_";
6539 else if (
"matching_mgt" == it->GetShortName())
6540 mgt = it->IsGood() ?
"G" : mgt;
6541 else if (
"seen_vct" == it->GetShortName())
6542 vct = it->IsGood() ?
"v" :
"_";
6543 else if (
"matching_vct" == it->GetShortName())
6544 vct = it->IsGood() ?
"V" : vct;
6545 else if (
"seen_nit" == it->GetShortName())
6546 nit = it->IsGood() ?
"n" :
"_";
6547 else if (
"matching_nit" == it->GetShortName())
6548 nit = it->IsGood() ?
"N" : nit;
6549 else if (
"seen_sdt" == it->GetShortName())
6550 sdt = it->IsGood() ?
"s" :
"_";
6551 else if (
"matching_sdt" == it->GetShortName())
6552 sdt = it->IsGood() ?
"S" : sdt;
6553 else if (
"seen_crypt" == it->GetShortName())
6554 crypt = it->IsGood() ?
"c" :
"_";
6555 else if (
"matching_crypt" == it->GetShortName())
6556 crypt = it->IsGood() ?
"C" : crypt;
6559 infoMap[
"signal"] = QString::number(sig);
6563 QString slock = (
"1" == infoMap[
"slock"]) ?
"L" :
"l";
6564 QString lockMsg = (slock==
"L") ? tr(
"Partial Lock") : tr(
"No Lock");
6565 QString sigMsg = allGood ? tr(
"Lock") : lockMsg;
6567 QString sigDesc = tr(
"Signal %1%").arg(sig,2);
6569 sigDesc +=
" | " + tr(
"S/N %1dB").arg(log10(snr), 3,
'f', 1);
6570 if (ber != 0xffffffff)
6571 sigDesc +=
" | " + tr(
"BE %1",
"Bit Errors").arg(ber, 2);
6572 if ((pos >= 0) && (pos < 100))
6573 sigDesc +=
" | " + tr(
"Rotor %1%").arg(pos,2);
6577 else if (tuned == 2)
6579 else if (tuned == 3)
6584 sigDesc = sigDesc + QString(
" | (%1%2%3%4%5%6%7%8%9) %10")
6585 .arg(tuneCode, slock, pat, pmt, mgt, vct,
6591 else if (!msg.isEmpty())
6594 infoMap[
"description"] = sigDesc;
6601 if (allGood || (pmt ==
"M"))
6610 bool timed_out =
false;
6625 LOG(VB_GENERAL, LOG_ERR,
LOC +
6626 "You have no OSD, but tuning has already taken too long.");
6652 static QString s_nextSrc =
GET_KEY(
"TV Playback",
"NEXTSOURCE");
6653 static QString s_togCards =
GET_KEY(
"TV Playback",
"NEXTINPUT");
6655 QString message = tr(
6656 "You should have received a channel lock by now. "
6657 "You can continue to wait for a signal, or you "
6658 "can change the channel with %1 or %2, change "
6659 "video source (%3), inputs (%4), etc.")
6660 .arg(s_chanUp, s_chanDown, s_nextSrc, s_togCards);
6663 { {tr(
"OK"),
"DIALOG_INFO_CHANNELLOCK_0" } },
6664 {
"",
"DIALOG_INFO_CHANNELLOCK_0",
true } });
6669 bool result =
false;
6735 dvdName = tr(
"DVD");
6739 mainStatus = tr(
"Menu");
6743 mainStatus = tr(
"Still Frame");
6747 int playingTitle = 0;
6748 int playingPart = 0;
6753 mainStatus = tr(
"Title: %1 (%2)").arg(playingTitle)
6755 subStatus = tr(
"Chapter: %1/%2").arg(playingPart).arg(totalParts);
6790 for (
uint i : std::as_const(list))
6791 ret += QString(
"%1,").arg(i);
6794 return ret.left(ret.length()-1);
6801 QVector<uint> tunable_cards;
6805 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6806 return tunable_cards;
6810 mplexid = (32767 == mplexid) ? 0 : mplexid;
6812 uint excluded_input = 0;
6820 for (
auto & input : inputs)
6822 if (input.m_sourceId != sourceid)
6825 if (input.m_mplexId &&
6826 input.m_mplexId != mplexid)
6829 if (!input.m_mplexId && input.m_chanId &&
6830 input.m_chanId != ChanId)
6833 tunable_cards.push_back(input.m_inputId);
6836 if (tunable_cards.empty())
6837 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6839 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) yes { %2 }").arg(ChanId).arg(
toCommaList(tunable_cards)));
6840 return tunable_cards;
6843void TV::Embed(
bool Embed, QRect Rect,
const QStringList& Data)
6868 if (!Data.isEmpty())
6880 if (Pause ^ waspaused)
6882 if (Pause ^ waspaused)
6907 LOG(VB_GENERAL, LOG_ERR,
LOC +
"no active ctx playingInfo.");
6934 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Pausing player: %1").arg(pause));
7017 QString message = QString(
"START_EPG %1 %2").arg(EditType).arg(arg);
7019 QCoreApplication::postEvent(
this, me);
7036 QString appName = tr(
"Video");
7042 appName = tr(
"DVD");
7044 lcd->switchToVolume(appName);
7070 const float kTimeStretchMin = 0.125;
7071 const float kTimeStretchMax = 2.0;
7072 const float kTimeStretchStep = 0.05F;
7076 if (new_ts_normal > kTimeStretchMax &&
7079 new_ts_normal = kTimeStretchMax;
7081 else if (new_ts_normal < kTimeStretchMin &&
7084 new_ts_normal = kTimeStretchMin;
7087 if (new_ts_normal > kTimeStretchMax ||
7088 new_ts_normal < kTimeStretchMin)
7151 QString message = tr(
"MythTV was set to sleep after %1 minutes and will exit in %d seconds.\n"
7152 "Do you wish to continue watching?")
7156 { { tr(
"Yes"),
"DIALOG_SLEEP_YES_0" },
7157 { tr(
"No"),
"DIALOG_SLEEP_NO_0" } }});
7178 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching TV, exiting");
7188 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Sleep timeout reached, exiting player.");
7206 QString message = tr(
"MythTV has been idle for %1 minutes and "
7207 "will exit in %d seconds. Are you still watching?")
7211 { { tr(
"Yes"),
"DIALOG_IDLE_YES_0" },
7212 { tr(
"No"),
"DIALOG_IDLE_NO_0" }}});
7235 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching LiveTV, exiting");
7248 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Idle timeout reached, leaving LiveTV");
7288 QString message = me->
Message();
7290 if (message.isEmpty())
7293 std::chrono::milliseconds
timeout = 0ms;
7294 if (me->ExtraDataCount() == 1)
7296 auto t = std::chrono::seconds(me->ExtraData(0).toInt());
7297 if (
t > 0s &&
t < 1000s)
7318 if (dce->GetData().userType() == qMetaTypeId<MythTVMenuNodeTuple>())
7322 QDomNode Node = Menu.GetNodeFromPath(data.m_path);
7323 if (dce->GetResult() == -1)
7330 OSDDialogEvent(dce->GetResult(), dce->GetResultText(), dce->GetData().toString());
7355 LOG(VB_GENERAL, LOG_NOTICE,
"DVD has been ejected, exiting playback");
7370 QString message = me->
Message();
7373 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
7375 if (me->ExtraDataCount() == 1)
7378 int value = me->ExtraData(0).toInt();
7408 if (me->ExtraDataCount() >= 2)
7410 width = me->ExtraData(0).toInt();
7411 height = me->ExtraData(1).toInt();
7413 if (me->ExtraDataCount() == 3)
7422 else if (message.startsWith(
"DONE_RECORDING"))
7424 std::chrono::seconds seconds = 0s;
7427 if (tokens.size() == NUMTOKENS)
7429 cardnum = tokens[1].toUInt();
7430 seconds = std::chrono::seconds(tokens[2].toInt());
7435 LOG(VB_GENERAL, LOG_ERR, QString(
"DONE_RECORDING event received "
7436 "with invalid number of arguments, "
7437 "%1 expected, %2 actual")
7439 .arg(tokens.size()-1));
7479 if (message.startsWith(
"ASK_RECORDING "))
7482 bool hasrec =
false;
7483 bool haslater =
false;
7484 if (tokens.size() >= 5)
7486 cardnum = tokens[1].toUInt();
7487 timeuntil = tokens[2].toInt();
7488 hasrec = (tokens[3].toInt() != 0);
7489 haslater = (tokens[4].toInt() != 0);
7491 LOG(VB_GENERAL, LOG_DEBUG,
7492 LOC + message + QString(
" hasrec: %1 haslater: %2")
7493 .arg(hasrec).arg(haslater));
7502 if (message.startsWith(
"QUIT_LIVETV"))
7504 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7517 if (message.startsWith(
"LIVETV_WATCH"))
7520 if (tokens.size() >= 3)
7522 cardnum = tokens[1].toUInt();
7523 watch = tokens[2].toInt();
7547 if (message.startsWith(
"LIVETV_CHAIN"))
7550 if ((tokens.size() >= 2) && tokens[1] ==
"UPDATE")
7559 if (message.startsWith(
"EXIT_TO_MENU"))
7568 if (message.startsWith(
"SIGNAL"))
7570 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7571 const QStringList& signalList = me->ExtraDataList();
7587 if (message.startsWith(
"NETWORK_CONTROL"))
7589 if ((tokens.size() >= 2) &&
7590 (tokens[1] !=
"ANSWER") && (tokens[1] !=
"RESPONSE"))
7592 QStringList tokens2 = message.split(
" ", Qt::SkipEmptyParts);
7593 if ((tokens2.size() >= 2) &&
7594 (tokens2[1] !=
"ANSWER") && (tokens2[1] !=
"RESPONSE"))
7603 if (message.startsWith(
"START_EPG"))
7605 int editType = tokens[1].toInt();
7606 QString arg = message.section(
" ", 2, -1);
7610 if (message.startsWith(
"COMMFLAG_START") && (tokens.size() >= 2))
7613 QDateTime evrecstartts;
7625 QString msg =
"COMMFLAG_REQUEST ";
7632 if (message.startsWith(
"COMMFLAG_UPDATE") && (tokens.size() >= 3))
7635 QDateTime evrecstartts;
7649 QStringList marks = tokens[2].split(
",", Qt::SkipEmptyParts);
7650 for (
int j = 0; j < marks.size(); j++)
7652 mark = marks[j].split(
":", Qt::SkipEmptyParts);
7653 if (marks.size() >= 2)
7654 newMap[mark[0].toULongLong()] =
static_cast<MarkTypes>(mark[1].toInt());
7664 if (message ==
"NOTIFICATION")
7685 recinfo.
ToMap(infoMap);
7702 map.insert(
"message_text", tr(
"Record"));
7710 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"Unknown recording during live tv.");
7723 cmdmsg = tr(
"Record");
7726 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record on");
7735 cmdmsg = tr(
"Cancel Record");
7738 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record off");
7786 sup &= ~kPictureAttributeSupported_Range;
7820 title = tr(
"Adjust Volume");
7837 if (Type ==
"EDIT_CUT_POINTS")
7843 "menu_cutlist.xml", tr(
"Edit Cut Points"),
7844 metaObject()->className(),
"TV Editing");
7850 else if (Type ==
"EDIT_CUT_POINTS_COMPACT")
7856 "menu_cutlist_compact.xml", tr(
"Edit Cut Points"),
7857 metaObject()->className(),
"TV Editing");
7863 else if (Type ==
"EXIT_EDIT_MODE")
7866 dialog.m_buttons.push_back( { tr(
"Save Cuts and Exit"),
"DIALOG_CUTPOINT_SAVEEXIT_0" } );
7867 dialog.m_buttons.push_back( { tr(
"Exit Without Saving"),
"DIALOG_CUTPOINT_REVERTEXIT_0" } );
7868 dialog.m_buttons.push_back( { tr(
"Save Cuts"),
"DIALOG_CUTPOINT_SAVEMAP_0" } );
7869 dialog.m_buttons.push_back( { tr(
"Undo Changes"),
"DIALOG_CUTPOINT_REVERT_0" } );
7870 dialog.m_back = {
"",
"DIALOG_CUTPOINT_DONOTHING_0",
true };
7874 map.insert(
"title", tr(
"Edit"));
7886 if (
Action ==
"DONOTHING" && osd)
7891 QStringList actions(
Action);
7893 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unrecognised cutpoint action");
7923 QString message = tr(
"This program is currently being edited");
7924 QString def = QString(
"DIALOG_EDITING_CONTINUE_%1").arg(
static_cast<int>(paused));
7926 { { tr(
"Continue Editing"), def,
false,
true },
7927 { tr(
"Do not edit"), QString(
"DIALOG_EDITING_STOP_%1").arg(
static_cast<int>(paused)) }},
7928 {
"", def,
true} });
7944 if (!WasPaused && paused)
7961 for (
auto it = newMap.cbegin(); it != newMap.cend(); ++it)
7962 infoMap.insert(it.key(), *it);
8021 if (osd &&
Action ==
"PROBE")
8029 else if (osd &&
Action ==
"OK")
8037 else if (osd &&
Action ==
"QUIT")
8051 const QString keys[4] = {
"XMLTV",
"callsign",
"channame",
"channum", };
8060 QMap<QString,bool> modifiable;
8061 modifiable[
"callsign"] = Info[
"callsign"].isEmpty();
8062 if (!modifiable[
"callsign"])
8064 QString unsetsign = tr(
"UNKNOWN%1",
"Synthesized callsign");
8065 int unsetcmpl = unsetsign.length() - 2;
8066 unsetsign = unsetsign.left(unsetcmpl);
8067 if (Info[
"callsign"].left(unsetcmpl) == unsetsign)
8068 modifiable[
"callsign"] =
true;
8070 modifiable[
"channame"] = Info[
"channame"].isEmpty();
8072 const std::array<const QString,2> xds_keys {
"callsign",
"channame", };
8073 for (
const auto & key : xds_keys)
8075 if (!modifiable[key])
8085 if ((key ==
"callsign") &&
8086 ((
tmp.length() > 5) || (
tmp.indexOf(
" ") >= 0)))
8098 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"result %1 text %2 action %3")
8099 .arg(QString::number(Result), Text,
Action));
8105 bool handled =
true;
8106 if (
Action.startsWith(
"DIALOG_"))
8108 Action.remove(
"DIALOG_");
8109 QStringList desc =
Action.split(
"_");
8110 bool valid = desc.size() == 3;
8116 else if (valid && desc[0] ==
"VIDEOEXIT")
8120 else if (valid && desc[0] ==
"SLEEP")
8124 else if (valid && desc[0] ==
"IDLE")
8128 else if (valid && desc[0] ==
"INFO")
8132 else if (valid && desc[0] ==
"EDITING")
8136 else if (valid && desc[0] ==
"ASKALLOW")
8140 else if (valid && desc[0] ==
"EDITOR")
8144 else if (valid && desc[0] ==
"CUTPOINT")
8148 else if ((valid && desc[0] ==
"DELETE") ||
8149 (valid && desc[0] ==
"CONFIRM"))
8158 LOG(VB_GENERAL, LOG_ERR,
"Unrecognised dialog event.");
8161 else if (Result < 0)
8178 else if (
Action ==
"CANCELPLAYLIST")
8204 else if (
Action ==
"TOGGLEMANUALZOOM")
8216 else if (
Action ==
"TOGGLESTRETCH")
8228 else if (
Action.startsWith(
"ADJUSTSTRETCH"))
8230 bool floatRead =
false;
8231 float stretch =
Action.right(
Action.length() - 13).toFloat(&floatRead);
8246 else if (
Action.startsWith(
"SELECTSCAN_"))
8278 else if (
Action.startsWith(
"TOGGLEPICCONTROLS"))
8283 else if (
Action ==
"TOGGLEASPECT")
8287 else if (
Action.startsWith(
"TOGGLEASPECT"))
8291 else if (
Action ==
"TOGGLEFILL")
8295 else if (
Action.startsWith(
"TOGGLEFILL"))
8299 else if (
Action ==
"MENU")
8303 else if (
Action ==
"AUTODETECT_FILL")
8313 if (
Action ==
"CHANGROUP_ALL_CHANNELS")
8319 Action.remove(
"CHANGROUP_");
8325 QString cur_channum;
8326 QString new_channum;
8332 new_channum = cur_channum;
8334 auto it = list.cbegin();
8335 for (; it != list.cend(); ++it)
8337 if ((*it).m_chanNum == cur_channum)
8343 if (it == list.end())
8348 if (it != list.end())
8349 new_channum = (*it).m_chanNum;
8352 LOG(VB_CHANNEL, LOG_INFO,
LOC +
8353 QString(
"Channel Group: '%1'->'%2'")
8354 .arg(cur_channum, new_channum));
8360 if (cur_channum != new_channum && !new_channum.isEmpty())
8379 else if (
Action ==
"SCHEDULE")
8392 else if (
Action.startsWith(
"JUMPCAST|"))
8394 QStringList tokens =
Action.split(
"|");
8395 if (tokens.size() == 3)
8397 else if (tokens.size() == 4)
8402 else if (
Action.startsWith(
"VISUALISER"))
8406 else if (
Action.startsWith(
"3D"))
8415 if (
Action ==
"TOGGLEBROWSE")
8417 else if (
Action ==
"PREVCHAN")
8419 else if (
Action.startsWith(
"SWITCHTOINPUT_"))
8424 else if (
Action ==
"EDIT")
8455 int chapter =
Action.right(3).toInt();
8460 int title =
Action.right(3).toInt();
8465 int angle =
Action.right(3).toInt();
8468 else if (
Action ==
"EDIT")
8473 else if (
Action ==
"TOGGLEAUTOEXPIRE")
8477 else if (
Action.startsWith(
"TOGGLECOMMSKIP"))
8481 else if (
Action ==
"QUEUETRANSCODE")
8485 else if (
Action ==
"QUEUETRANSCODE_AUTO")
8489 else if (
Action ==
"QUEUETRANSCODE_HIGH")
8493 else if (
Action ==
"QUEUETRANSCODE_MEDIUM")
8497 else if (
Action ==
"QUEUETRANSCODE_LOW")
8519 LOG(VB_GENERAL, LOG_ERR,
LOC +
8520 "Unknown menu action selected: " +
Action);
8531 bool visible =
false;
8544 if (
Action ==
"CHANNELLOCK")
8549#define BUTTON(action, text) \
8550 result = Context.AddButton(Menu, active, (action), (text), "", false, "")
8551#define BUTTON2(action, textActive, textInactive) \
8552 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), false, "")
8553#define BUTTON3(action, textActive, textInactive, isMenu) \
8554 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), (isMenu), "")
8569 const QString &actionName = Context.
m_action;
8571 bool result =
false;
8574 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8591 if (actionName ==
"DIALOG_CUTPOINT_MOVEPREV_0")
8599 BUTTON2(actionName, tr(
"Move Previous Cut End Here"), tr(
"Move Start of Cut Here"));
8602 else if (actionName ==
"DIALOG_CUTPOINT_MOVENEXT_0")
8610 BUTTON2(actionName, tr(
"Move Next Cut Start Here"), tr(
"Move End of Cut Here"));
8613 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOBEGINNING_0")
8616 BUTTON(actionName, tr(
"Cut to Beginning"));
8618 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOEND_0")
8623 BUTTON(actionName, tr(
"Cut to End"));
8626 else if (actionName ==
"DIALOG_CUTPOINT_DELETE_0")
8629 BUTTON2(actionName, tr(
"Delete This Cut"), tr(
"Join Surrounding Cuts"));
8631 else if (actionName ==
"DIALOG_CUTPOINT_NEWCUT_0")
8634 BUTTON(actionName, tr(
"Add New Cut"));
8636 else if (actionName ==
"DIALOG_CUTPOINT_UNDO_0")
8640 QString text = tr(
"Undo - %1");
8641 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8644 else if (actionName ==
"DIALOG_CUTPOINT_REDO_0")
8648 QString text = tr(
"Redo - %1");
8649 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8652 else if (actionName ==
"DIALOG_CUTPOINT_CLEARMAP_0")
8654 BUTTON(actionName, tr(
"Clear Cuts"));
8656 else if (actionName ==
"DIALOG_CUTPOINT_INVERTMAP_0")
8658 BUTTON(actionName, tr(
"Reverse Cuts"));
8660 else if (actionName ==
"DIALOG_CUTPOINT_LOADCOMMSKIP_0")
8662 BUTTON(actionName, tr(
"Load Detected Commercials"));
8664 else if (actionName ==
"DIALOG_CUTPOINT_REVERT_0")
8666 BUTTON(actionName, tr(
"Undo Changes"));
8668 else if (actionName ==
"DIALOG_CUTPOINT_REVERTEXIT_0")
8670 BUTTON(actionName, tr(
"Exit Without Saving"));
8672 else if (actionName ==
"DIALOG_CUTPOINT_SAVEMAP_0")
8674 BUTTON(actionName, tr(
"Save Cuts"));
8676 else if (actionName ==
"DIALOG_CUTPOINT_SAVEEXIT_0")
8678 BUTTON(actionName, tr(
"Save Cuts and Exit"));
8692 if (!text.isEmpty())
8693 BUTTON(actionName, text);
8705 const QString &actionName = Context.
m_action;
8707 bool result =
false;
8712 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8802 if (
prefix ==
"SELECTSUBTITLE_")
8804 else if (
prefix ==
"SELECTRAWTEXT_")
8806 else if (
prefix ==
"SELECTCC708_")
8808 else if (
prefix ==
"SELECTCC608_")
8810 else if (
prefix ==
"SELECTTTC_")
8812 else if (
prefix ==
"SELECTAUDIO_")
8835 static const std::array<const speed,9> s_speeds {{
8836 { 0,
"", tr(
"Adjust")},
8837 { 50,
"0.5", tr(
"0.5x")},
8838 { 90,
"0.9", tr(
"0.9x")},
8839 {100,
"1.0", tr(
"1.0x")},
8840 {110,
"1.1", tr(
"1.1x")},
8841 {120,
"1.2", tr(
"1.2x")},
8842 {130,
"1.3", tr(
"1.3x")},
8843 {140,
"1.4", tr(
"1.4x")},
8844 {150,
"1.5", tr(
"1.5x")},
8847 for (
const auto & speed : s_speeds)
8869 BUTTON(
"CHANGROUP_ALL_CHANNELS", tr(
"All Channels"));
8870 ChannelGroupList::const_iterator it;
8874 QString
action =
prefix + QString::number(it->m_grpId);
8884 static constexpr std::array<const uint,3> kCasOrd { 0, 2, 1 };
8885 for (
uint csm : kCasOrd)
8902 QString chapter1 = QString(
"%1").arg(i+1, size, 10, QChar(48));
8903 QString chapter2 = QString(
"%1").arg(i+1, 3 , 10, QChar(48));
8905 QString desc = chapter1 + QString(
" (%1)").arg(timestr);
8918 QString angleIdx = QString(
"%1").arg(i, 3, 10, QChar(48));
8933 QString titleIdx = QString(
"%1").arg(i, 3, 10, QChar(48));
8946 QVector <QString> addednames;
8948 for (
auto & input : inputs)
8950 if (input.m_inputId == inputid ||
8951 addednames.contains(input.m_displayName))
8954 addednames += input.m_displayName;
8955 QString
action = QString(
"SWITCHTOINPUT_") +
8956 QString::number(input.m_inputId);
8968 uint sourceid =
info[
"sourceid"].toUInt();
8969 QMap<uint, bool> sourceids;
8971 for (
auto & input : inputs)
8973 if (input.m_sourceId == sourceid ||
8974 sourceids[input.m_sourceId])
8977 sourceids[input.m_sourceId] =
true;
8978 QString
action = QString(
"SWITCHTOINPUT_") +
8979 QString::number(input.m_inputId);
8986 if (actionName ==
"TOGGLEAUDIOSYNC")
8988 BUTTON(actionName, tr(
"Adjust Audio Sync"));
8992 BUTTON(actionName, tr(
"None"));
8994 else if (actionName ==
"DISABLEUPMIX")
8999 BUTTON(actionName, tr(
"Disable Audio Upmixer"));
9002 else if (actionName ==
"ENABLEUPMIX")
9007 BUTTON(actionName, tr(
"Auto Detect"));
9010 else if (actionName ==
"AUTODETECT_FILL")
9017 BUTTON(actionName, tr(
"Auto Detect"));
9020 else if (actionName ==
"TOGGLEMANUALZOOM")
9022 BUTTON(actionName, tr(
"Manual Zoom Mode"));
9024 else if (actionName ==
"DISABLESUBS")
9028 BUTTON(actionName, tr(
"Disable Subtitles"));
9030 else if (actionName ==
"ENABLESUBS")
9034 BUTTON(actionName, tr(
"Enable Subtitles"));
9036 else if (actionName ==
"DISABLEFORCEDSUBS")
9042 BUTTON(actionName, tr(
"Disable Forced Subtitles"));
9045 else if (actionName ==
"ENABLEFORCEDSUBS")
9051 BUTTON(actionName, tr(
"Enable Forced Subtitles"));
9054 else if (actionName ==
"DISABLEEXTTEXT")
9058 BUTTON(actionName, tr(
"Disable External Subtitles"));
9060 else if (actionName ==
"ENABLEEXTTEXT")
9064 BUTTON(actionName, tr(
"Enable External Subtitles"));
9066 else if (actionName ==
"TOGGLETTM")
9069 BUTTON(actionName, tr(
"Toggle Teletext Menu"));
9071 else if (actionName ==
"TOGGLESUBZOOM")
9074 BUTTON(actionName, tr(
"Adjust Subtitle Zoom"));
9076 else if (actionName ==
"TOGGLESUBDELAY")
9082 BUTTON(actionName, tr(
"Adjust Subtitle Delay"));
9085 else if (actionName ==
"PAUSE")
9088 BUTTON2(actionName, tr(
"Play"), tr(
"Pause"));
9090 else if (actionName ==
"TOGGLESTRETCH")
9092 BUTTON(actionName, tr(
"Toggle"));
9094 else if (actionName ==
"TOGGLEBROWSE")
9097 BUTTON(actionName, tr(
"Toggle Browse Mode"));
9099 else if (actionName ==
"CANCELPLAYLIST")
9102 BUTTON(actionName, tr(
"Cancel Playlist"));
9104 else if (actionName ==
"DEBUGOSD")
9106 BUTTON(actionName, tr(
"Playback Data"));
9108 else if (actionName ==
"JUMPFFWD")
9111 BUTTON(actionName, tr(
"Jump Ahead"));
9113 else if (actionName ==
"JUMPRWND")
9116 BUTTON(actionName, tr(
"Jump Back"));
9118 else if (actionName ==
"JUMPTODVDROOTMENU")
9123 BUTTON2(actionName, tr(
"DVD Root Menu"), tr(
"Top menu"));
9126 else if (actionName ==
"JUMPTOPOPUPMENU")
9129 BUTTON(actionName, tr(
"Popup menu"));
9131 else if (actionName ==
"JUMPTODVDTITLEMENU")
9134 BUTTON(actionName, tr(
"DVD Title Menu"));
9136 else if (actionName ==
"JUMPTODVDCHAPTERMENU")
9139 BUTTON(actionName, tr(
"DVD Chapter Menu"));
9141 else if (actionName ==
"PREVCHAN")
9144 BUTTON(actionName, tr(
"Previous Channel"));
9146 else if (actionName ==
"GUIDE")
9148 BUTTON(actionName, tr(
"Program Guide"));
9150 else if (actionName ==
"FINDER")
9152 BUTTON(actionName, tr(
"Program Finder"));
9154 else if (actionName ==
"VIEWSCHEDULED")
9156 BUTTON(actionName, tr(
"Upcoming Recordings"));
9158 else if (actionName ==
"SCHEDULE")
9160 BUTTON(actionName, tr(
"Edit Recording Schedule"));
9162 else if (actionName ==
"DIALOG_JUMPREC_X_0")
9164 BUTTON3(actionName, tr(
"Recorded Program"),
"",
true);
9170 else if (actionName ==
"JUMPPREV")
9185 else if (actionName ==
"EDIT")
9191 BUTTON2(actionName, tr(
"Edit Channel"), tr(
"Edit Recording"));
9194 else if (actionName ==
"TOGGLEAUTOEXPIRE")
9200 tr(
"Turn Auto-Expire OFF"), tr(
"Turn Auto-Expire ON"));
9203 else if (actionName ==
"QUEUETRANSCODE")
9208 BUTTON2(actionName, tr(
"Stop Transcoding"), tr(
"Default"));
9211 else if (actionName ==
"QUEUETRANSCODE_AUTO")
9216 BUTTON(actionName, tr(
"Autodetect"));
9219 else if (actionName ==
"QUEUETRANSCODE_HIGH")
9224 BUTTON(actionName, tr(
"High Quality"));
9227 else if (actionName ==
"QUEUETRANSCODE_MEDIUM")
9232 BUTTON(actionName, tr(
"Medium Quality"));
9235 else if (actionName ==
"QUEUETRANSCODE_LOW")
9240 BUTTON(actionName, tr(
"Low Quality"));
9247 BUTTON(actionName, tr(
"Cast"));
9258 if (!text.isEmpty())
9259 BUTTON(actionName, text);
9319 QString cur_channum = QString();
9322 if (!prev_channum.isEmpty() && prev_channum != cur_channum)
9374 QString text = Menu.
Translate(Node.toElement().attribute(
"text", Menu.
GetName()));
9375 const char* windowtitle {
"???" };
9381 Menu.
Show(Node, Selected, *
this, &
menu);
9382 QDomNode parent = Node.parentNode();
9383 if (!parent.parentNode().isNull())
9387 menu.m_back = {
"", v };
9396 map.insert(
"title", tr(
"Edit"));
9405 (void)tr(
"Playback Menu");
9406 (void)tr(
"Playback Compact Menu");
9408 (void)tr(
"Select Audio Track");
9409 (void)tr(
"Visualisation");
9411 (void)tr(
"Change Aspect Ratio");
9412 (void)tr(
"Adjust Fill");
9413 (void)tr(
"Adjust Picture");
9415 (void)tr(
"Advanced");
9416 (void)tr(
"Video Scan");
9417 (void)tr(
"Deinterlacer");
9418 (void)tr(
"Subtitles");
9419 (void)tr(
"Select Subtitle");
9420 (void)tr(
"Text Subtitles");
9421 (void)tr(
"Select ATSC CC");
9422 (void)tr(
"Select VBI CC");
9423 (void)tr(
"Select Teletext CC");
9424 (void)tr(
"Playback");
9425 (void)tr(
"Adjust Time Stretch");
9426 (void)tr(
"Picture-in-Picture");
9428 (void)tr(
"Channel Groups");
9429 (void)tr(
"Navigate");
9430 (void)tr(
"Commercial Auto-Skip");
9431 (void)tr(
"Chapter");
9434 (void)tr(
"Schedule");
9436 (void)tr(
"Jump to Program");
9437 (void)tr(
"Switch Input");
9438 (void)tr(
"Switch Source");
9440 (void)tr(
"Begin Transcoding");
9442 (void)tr(
"Recorded");
9443 (void)tr(
"Upcoming");
9446 (void)tr(
"Edit Cut Points");
9447 (void)tr(
"Edit Cut Points (Compact)");
9448 (void)tr(
"Cut List Options");
9456 "menu_playback.xml", tr(
"Playback Menu"),
9457 metaObject()->className(),
"TV Playback");
9459 "menu_playback_compact.xml", tr(
"Playback Compact Menu"),
9460 metaObject()->className(),
"TV Playback");
9472 if (Level < 0 || Level > 1)
9486 QList<QString> titles_seen;
9492 for (
auto *pi : *infoList)
9494 if (pi->GetRecordingGroup() !=
"LiveTV" || LiveTVInAllPrograms ||
9495 pi->GetRecordingGroup() == currecgroup)
9503 QMap<QString,ProgramList>::const_iterator Iprog;
9507 auto progIndex =
static_cast<uint>(plist.
size());
9508 const QString& group = Iprog.key();
9513 if (progIndex == 1 && Level == 0)
9515 dialog.m_buttons.push_back( {Iprog.key(), QString(
"JUMPPROG %1 0").arg(group) });
9517 else if (progIndex > 1 && Level == 0)
9519 QString act = QString(
"DIALOG_%1_%2_1")
9521 dialog.m_buttons.push_back( {group, act,
true, Selected == group });
9523 else if (Level == 1 && Iprog.key() == Category)
9525 for (
auto pit = plist.
begin(); pit != plist.
end(); ++pit)
9529 if (titles_seen.contains(
p->GetTitle()))
9532 titles_seen.push_back(
p->GetTitle());
9535 for (
auto *q : plist)
9539 if (q->GetTitle() !=
p->GetTitle())
9542 dialog.m_buttons.push_back( { q->GetSubtitle().isEmpty() ?
9543 q->GetTitle() : q->GetSubtitle(),
9544 QString(
"JUMPPROG %1 %2").arg(Iprog.key()).arg(j) });
9552 while (!infoList->empty())
9554 delete infoList->back();
9555 infoList->pop_back();
9560 if (!Category.isEmpty())
9563 dialog.m_back = { Category,
"DIALOG_" +
ACTION_JUMPREC +
"_X_0" };
9564 else if (Level == 0)
9578 bool recorded = (
ProgInfo.GetFilesize() > 0);
9579 QString table = recorded ?
"recordedcredits" :
"credits";
9586 query.
prepare(QString(
"SELECT role, people.name,"
9587 " roles.name, people.person FROM %1"
9589 " LEFT JOIN people ON"
9590 " credits.person = people.person"
9591 " LEFT JOIN roles ON"
9592 " credits.roleid = roles.roleid"
9593 " WHERE credits.chanid = :CHANID"
9594 " AND credits.starttime = :STARTTIME"
9595 " AND role IN ('guest','actor','guest_star')"
9596 " ORDER BY role, priority;").arg(table));
9601 if (query.
exec() && query.
size() > 0)
9610 role = query.
value(0).toString();
9626 int pid = query.
value(3).toInt();
9627 pname = QString::fromUtf8(query.
value(1)
9628 .toByteArray().constData()) +
9629 "|" + QString::number(pid);
9630 character = QString::fromUtf8(query.
value(2)
9631 .toByteArray().constData());
9633 if (role ==
"actor")
9634 m_actors.append(qMakePair(pname, character));
9635 else if (role ==
"guest_star")
9637 else if (role ==
"guest")
9638 m_guests.append(qMakePair(pname, character));
9645 const QVector<string_pair> & people)
9647 for (
const auto & [actor, role] : std::as_const(people))
9651 dialog.
m_buttons.push_back( {actor.split(
'|')[0],
9652 QString(
"JUMPCAST|%1").arg(actor),
true} );
9656 dialog.
m_buttons.push_back( {QString(
"%1 as %2")
9657 .arg(actor.split(
'|')[0], role),
9658 QString(
"JUMPCAST|%1").arg(actor),
true} );
9676 const QString & category)
9680 if (category.isEmpty())
9682 dialog.
m_buttons.push_back( {
"Recorded",
9683 QString(
"JUMPCAST|%1|%2|Recorded").arg(actor).arg(person_id) } );
9684 dialog.m_buttons.push_back( {
"Upcoming",
9685 QString(
"JUMPCAST|%1|%2|Upcoming").arg(actor).arg(person_id) } );
9690 if (category ==
"Upcoming")
9702 QString table =
"recordedcredits";
9704 query.
prepare(QString(
"SELECT chanid, starttime from %1"
9705 " where person = :PERSON"
9706 " ORDER BY starttime;").arg(table));
9709 QDateTime starttime;
9710 if (query.
exec() && query.
size() > 0)
9714 int chanid = query.
value(0).toInt();
9716 auto *pi =
new ProgramInfo(chanid, starttime.toUTC());
9717 if (!pi->GetTitle().isEmpty() &&
9718 pi->GetRecordingGroup() !=
"LiveTV" &&
9719 pi->GetRecordingGroup() !=
"Deleted")
9732 show = pi->GetTitle();
9735 if (!pi->GetSubtitle().isEmpty())
9737 show += QString(
" %1x%2 %3").arg(pi->GetSeason())
9738 .arg(pi->GetEpisode())
9739 .arg(pi->GetSubtitle());
9742 dialog.m_buttons.push_back( {
show,
9743 QString(
"JUMPPROG %1 %2").arg(actor).arg(++idx) });
9760 if (!message.isEmpty())
9773 desc = tr(
"Auto-Expire OFF");
9778 desc = tr(
"Auto-Expire ON");
9783 if (!desc.isEmpty())
9799 if (!desc.isEmpty())
9808 if (!Desc.isEmpty())
9824 for (
const auto&
action : std::as_const(Actions))
9826 if (!
action.startsWith(
"JUMPPROG"))
9830 QString key =
action.section(
" ",1,-2);
9831 uint index =
action.section(
" ",-1,-1).toUInt(&ok);
9848 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to locate jump to program '%1' @ %2")
9849 .arg(key,
action.section(
" ",-1,-1)));
9871 QTimer::singleShot(0,
this, Jump);
9879 LOG(VB_GENERAL, LOG_ERR,
"Failed to open jump to program GUI");
9887 std::chrono::minutes mins { 0min };
9910 if (Time.length() > 11)
9912 bool intRead =
false;
9913 mins = std::chrono::minutes(Time.right(Time.length() - 11).toUInt(&intRead));
9926 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time " + Time);
9931 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time string " + Time);
9943 out = tr(
"Sleep") +
" " + QString::number(mins.count());
9956 errorText = tr(
"MythTV is already using all available "
9957 "inputs for the channel you selected. "
9958 "If you want to watch an in-progress recording, "
9959 "select one from the playback menu. If you "
9960 "want to watch Live TV, cancel one of the "
9961 "in-progress recordings from the delete "
9965 errorText = tr(
"Error: MythTV is using all inputs, "
9966 "but there are no active recordings?");
9969 errorText = tr(
"MythTV has no capture cards defined. "
9970 "Please run the mythtv-setup program.");
10107 else if (!dvd->StartOfTitle())
10113 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10114 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10137 bool in_menu = dvd->IsInMenu();
10138 if (in_still && !dvd->NumMenuButtons())
10140 dvd->SkipStillFrame();
10143 else if (!dvd->EndOfTitle() && !in_still && !in_menu)
10147 else if (!in_still && !in_menu)
10149 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10150 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10151 std::chrono::seconds currentTime = dvd->GetCurrentTime();
10196 bool allowed =
false;
10219 videotype = tr(
"Live TV");
10221 videotype = tr(
"this DVD");
10225 videotype = tr(
"this Video");
10228 if (videotype.isEmpty())
10229 videotype = tr(
"this recording");
10233 dialog.m_buttons.push_back({tr(
"Exit %1").arg(videotype),
ACTION_STOP});
10235 dialog.m_buttons.push_back({tr(
"Exit Without Saving"),
"DIALOG_VIDEOEXIT_CLEARLASTPLAYEDPOSITION_0"});
10238 dialog.m_buttons.push_back({tr(
"Delete this recording"),
"DIALOG_VIDEOEXIT_CONFIRMDELETE_0"});
10240 dialog.m_buttons.push_back({tr(
"Keep watching"),
"DIALOG_VIDEOEXIT_KEEPWATCHING_0"});
10241 dialog.m_back = {
"",
"DIALOG_VIDEOEXIT_KEEPWATCHING_0",
true };
10242 emit ChangeOSDDialog(dialog);
10244 if (m_videoExitDialogTimerId)
10245 KillTimer(m_videoExitDialogTimerId);
10246 m_videoExitDialogTimerId = StartTimer(kVideoExitDialogTimeout, __LINE__);
10256 LOG(VB_GENERAL, LOG_ERR,
"It is unsafe to delete at the moment");
10264 LOG(VB_GENERAL, LOG_ERR,
"This program cannot be deleted at this time.");
10271 QString message = tr(
"Cannot delete program ") + QString(
"%1 ").arg(pginfo.
GetTitle());
10274 message += QString(
"\"%1\" ").arg(pginfo.
GetSubtitle());
10278 message += tr(
"because it is not a recording.");
10282 message += tr(
"because it is in use by");
10285 for (
int i = 0; (i + 2) < byWho.size(); i += 3)
10291 message +=
" " + byWho[i+2];
10295 {{ tr(
"OK"),
"DIALOG_DELETE_OK_0" }},
10296 {
"",
"DIALOG_DELETE_OK_0",
true }});
10319 QString message = QString(
"%1\n%2\n%3")
10320 .arg(Title, infoMap[
"title"], infoMap[
"timedate"]);
10326 if (Title ==
"End Of Recording")
10328 dialog.m_buttons.push_back({tr(
"Delete it, but allow it to re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10329 dialog.m_buttons.push_back({tr(
"Delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10330 dialog.m_buttons.push_back({tr(
"Save it so I can watch it again"),
ACTION_STOP,
false,
true});
10334 dialog.m_buttons.push_back({tr(
"Yes, and allow re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10335 dialog.m_buttons.push_back({tr(
"Yes, delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10336 dialog.m_buttons.push_back({tr(
"No, keep it"),
ACTION_STOP,
false,
true});
10338 dialog.m_back = {
"",
"DIALOG_PLAY_0_0",
true };
10362 if (
Action ==
"DELETEANDRERECORD" && delete_ok)
10369 else if (
Action ==
"JUSTDELETE" && delete_ok)
10375 else if (
Action ==
"CONFIRMDELETE")
10380 else if (
Action ==
"KEEPWATCHING" && !near_end)
10384 else if (
Action ==
"CLEARLASTPLAYEDPOSITION")
10463 bool paused =
false;
10515 case Qt::ApplicationState::ApplicationSuspended:
10517 LOG(VB_GENERAL, LOG_NOTICE,
"Exiting playback on app suspecnd");
10541 LOG(VB_GENERAL, LOG_ERR,
"An exception occurred");
std::vector< ChannelInfo > ChannelInfoList
An action (for this plugin) consists of a description, and a set of key sequences.
static bool IsTunerShared(uint inputidA, uint inputidB)
static QString GetStartChannel(uint inputid)
static std::vector< uint > GetInputGroups(uint inputid)
static uint GetSourceID(uint inputid)
static bool SetStartChannel(uint inputid, const QString &channum)
static QString GetDisplayName(uint inputid)
static ChannelGroupList GetChannelGroups(bool includeEmpty=true)
static QStringList GetValidRecorderList(uint chanid, const QString &channum)
Returns list of the recorders that have chanid or channum in their sources.
static uint GetMplexID(uint sourceid, const QString &channum)
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
static QString GetIcon(uint chanid)
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
static uint GetNextChannel(const ChannelInfoList &sorted, uint old_chanid, uint mplexid_restriction, uint chanid_restriction, ChannelChangeDirection direction, bool skip_non_visible=true, bool skip_same_channum_and_callsign=false, bool skip_other_sources=false)
static QString GetChanNum(int chan_id)
Returns the channel-number string of the given channel.
static ChannelInfoList GetChannels(uint sourceid, bool visible_only, const QString &group_by=QString(), uint channel_groupid=0)
static uint GetSourceIDForChannel(uint chanid)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
static const Type kEventType
static bool ChangeJobCmds(int jobID, int newCmds)
static bool QueueJob(int jobType, uint chanid, const QDateTime &recstartts, const QString &args="", const QString &comment="", QString host="", int flags=0, int status=JOB_QUEUED, QDateTime schedruntime=QDateTime())
static bool IsJobQueuedOrRunning(int jobType, uint chanid, const QDateTime &recstartts)
int getLCDWidth(void) const
void switchToChannel(const QString &channum="", const QString &title="", const QString &subtitle="")
void setChannelProgress(const QString &time, float value)
QString GetID(void) const
void JumpTo(int num, std::chrono::seconds pos)
QString GetChannelName(int pos=-1) const
void SetProgram(const ProgramInfo &pginfo)
QString GetInputType(int pos=-1) const
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
void start(QRunnable *runnable, const QString &debugName, int priority=0)
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
void exit(int retcode=0)
Use this to exit from the thread if you are using a Qt event loop.
std::chrono::milliseconds m_audioOffset
bool IsHDMVNavigation(void) const
Dialog asking for user confirmation.
void emitTVPlaybackStarted(void)
void UnregisterForPlayback(QObject *sender)
Unregister sender from being called when TVPlaybackAboutToStart signal is emitted.
void emitTVPlaybackSought(qint64 position)
void emitTVPlaybackStopped(void)
QString GetHostName(void)
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
void SaveSetting(const QString &key, int newValue)
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
Register sender for TVPlaybackAboutToStart signal.
void emitTVPlaybackUnpaused(void)
void SendSystemEvent(const QString &msg)
void emitTVPlaybackPaused(void)
void emitTVPlaybackAborted(void)
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
void dispatch(const MythEvent &event)
void SendMessage(const QString &message)
void emitTVPlaybackPlaying(void)
int GetNumSetting(const QString &key, int defaultval=0)
bool GetBoolSetting(const QString &key, bool defaultval=false)
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
static MythDB * getMythDB()
int NumPartsInTitle(void) const
bool GoBack(void)
Attempts to back-up by trying to jump to the 'Go up' PGC, the root menu or the title menu in turn.
std::chrono::seconds GetTotalTimeOfTitle(void) const
get the total time of the title in seconds 90000 ticks = 1 sec
bool IsInStillFrame(void) const override
bool GetNameAndSerialNum(QString &Name, QString &SerialNumber) override
Get the dvd title and serial num.
void GetPartAndTitle(int &Part, int &Title) const
T dequeue()
Removes item from front of list and returns a copy. O(1).
void enqueue(const T &d)
Adds item to the back of the list. O(1).
bool SwitchToGUI(bool Wait=false)
Switches to the GUI resolution.
virtual bool UsingVideoModes()
bool NextModeIsLarger(QSize Size)
Check whether the next mode is larger in size than the current mode.
This class is used as a container for messages.
const QString & Message() const
static const Type kUpdateTvProgressEventType
static const Type kUpdateBrowseInfoEventType
static const Type kMythEventMessage
static const Type kMythUserMessage
A custom event that represents a mouse gesture.
static const Type kEventType
QWidget * GetPaintWindow()
void ClearKeyContext(const QString &Context)
static void DisableScreensaver()
QString GetActionText(const QString &Context, const QString &Action) const
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
MythDisplay * GetDisplay()
MythScreenStack * GetMainStack()
static bool ScreenShot(int Width=0, int Height=0, QString Filename="")
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
bool IsExitingToMain() const
void MoveResize(QRect &Geometry)
MythScreenStack * GetStack(const QString &Stackname)
static QString GetKey(const QString &Context, const QString &Action)
bool KeyLongPressFilter(QEvent **Event, QScopedPointer< QEvent > &NewEvent)
static void RestoreScreensaver()
static MythNotificationCenter * GetInstance(void)
returns the MythNotificationCenter singleton
bool Queue(const MythNotification ¬ification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
std::vector< MythOSDDialogButton > m_buttons
void addListener(QObject *listener)
Add a listener to the observable.
void removeListener(QObject *listener)
Remove a listener to the observable.
bool IsInMenu(void) const override
QStringList GetTracks(uint Type)
uint GetTrackCount(uint Type)
bool HandleProgramEditorActions(const QStringList &Actions)
virtual void UpdateSliderInfo(osdInfo &Info, bool PaddedFields=false)
void SetWatched(bool ForceWatched=false)
Determines if the recording should be considered watched.
void GetCodecDescription(InfoMap &Map)
virtual bool Rewind(float seconds)
virtual int GetNumAngles(void) const
uint64_t TranslatePositionAbsToRel(uint64_t position) const
CommSkipMode GetAutoCommercialSkip(void)
uint64_t TranslatePositionMsToFrame(std::chrono::milliseconds position, bool use_cutlist) const
virtual QString GetTitleName(int) const
virtual int GetNumTitles(void) const
virtual QString GetAngleName(int) const
virtual std::chrono::seconds GetTitleDuration(int) const
void SetWatchingRecording(bool mode)
uint64_t TranslatePositionRelToAbs(uint64_t position) const
virtual bool JumpToFrame(uint64_t frame)
virtual bool FastForward(float seconds)
virtual int GetCurrentAngle(void) const
virtual int GetNumChapters(void)
uint64_t GetCurrentFrameCount(void) const
QString GetError(void) const
virtual int GetCurrentTitle(void) const
void SkipCommercials(int direction)
MythVideoOutput * GetVideoOutput(void)
bool IsPaused(void) const
bool IsPlaying(std::chrono::milliseconds wait_in_msec=0ms, bool wait_for=true) const
uint64_t GetFramesPlayed(void) const
void SetLength(std::chrono::seconds len)
virtual int GetCurrentChapter(void)
bool IsNearEnd(void)
Returns true iff near end of recording.
bool IsErrored(void) const
virtual uint64_t GetBookmark(void)
bool GetLimitKeyRepeat(void) const
float GetPlaySpeed(void) const
float ComputeSecs(uint64_t position, bool use_cutlist) const
bool GetEditMode(void) const
QString GetXDS(const QString &key) const
virtual void GetChapterTimes(QList< std::chrono::seconds > ×)
virtual bool SwitchAngle(int)
bool GetAllowForcedSubtitles(void) const
virtual bool SwitchTitle(int)
bool Play(float speed=1.0, bool normal=true, bool unpauseaudio=true)
void JumpChapter(int chapter)
void SetCommBreakMap(const frm_dir_map_t &NewMap)
void SetAutoCommercialSkip(CommSkipMode autoskip)
float GetFrameRate(void) const
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
virtual MythScreenType * GetTopScreen(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
A QElapsedTimer based timer to replace use of QTime as a timer.
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
bool isRunning(void) const
Returns true if start() or restart() has been called at least once since construction and since any c...
void start(void)
starts measuring elapsed time.
static void SetState(const QVariantMap &NewState)
void DeleteAllChildren(void)
Delete all child widgets.
StereoscopicMode m_stereoOverride
AspectOverrideMode m_aspectOverrideMode
AdjustFillMode m_adjustFillMode
PictureAttributeSupported m_supportedAttributes
int GetValue(PictureAttribute Attribute)
std::chrono::milliseconds m_timecode
bool HasSoftwareFrames() const
void SetScanOverride(FrameScanType Scan)
FrameScanType NextScanOverride()
FrameScanType GetScanTypeWithOverride() const
QStringList m_visualiserList
void SetValues(const QString &Window, const QHash< QString, int > &Map, OSDTimeout Timeout)
bool DialogVisible(const QString &Window=QString())
void ResetWindow(const QString &Window)
bool DialogHandleGesture(MythGestureEvent *Event)
void DialogGetText(InfoMap &Map)
bool DialogHandleKeypress(QKeyEvent *Event)
void SetFunctionalWindow(const QString &Window, enum OSDFunctionalType Type)
bool IsWindowVisible(const QString &Window)
void HideWindow(const QString &Window) override
static int GetCount(void)
void SetRingBuffer(MythMediaBuffer *Buffer)
void SetPlayingInfo(const ProgramInfo *info)
assign programinfo to the context
bool IsErrored(void) const
This is set if the player encountered some irrecoverable error.
StringDeque m_prevChan
Previous channels.
QStringList m_lastSignalMsg
QString GetPlayMessage(void) const
void SetPseudoLiveTV(const ProgramInfo *pi, PseudoState new_state)
PseudoState m_pseudoLiveTVState
MythTimer m_lastSignalMsgTime
void LockState(void) const
void LockPlayingInfo(const char *file, int line) const
TVState GetState(void) const
static constexpr std::chrono::milliseconds kSMExitTimeout
Timeout after last Signal Monitor message for ignoring OSD when exiting.
bool HasPlayer(void) const
bool IsPlayerErrored(void) const
void PushPreviousChannel(void)
most recently selected channel to the previous channel list
bool IsPlayerPlaying(void) const
std::chrono::seconds m_rewtime
int m_ffRewState
0 == normal, +1 == fast forward, -1 == rewind
TVState DequeueNextState(void)
void ForceNextStateNone(void)
Removes any pending state changes, and puts kState_None on the queue.
void UnlockDeletePlayer(const char *file, int line) const
allow player to be deleted.
void UnlockState(void) const
int m_ffRewIndex
Index into m_ffRewSpeeds for FF and Rewind speeds.
RemoteEncoder * m_recorder
void UpdateTVChain(const QStringList &data=QStringList())
bool HandlePlayerSpeedChangeFFRew(void)
bool InStateChange(void) const
InfoMap m_lastSignalUIInfo
void SetPlayer(MythPlayer *newplayer)
int m_ffRewSpeed
Caches value of m_ffRewSpeeds[m_ffRewIndex].
bool IsPlayerChangingBuffers(void) const
void LockDeletePlayer(const char *file, int line) const
prevent MythPlayer from being deleted used to ensure player can only be deleted after osd in TV() is ...
void SetRecorder(RemoteEncoder *rec)
bool IsRecorderErrored(void) const
bool HandlePlayerSpeedChangeEOF(void)
float m_tsNormal
Time stretch speed, 1.0F for normal playback.
std::chrono::seconds m_fftime
QString GetPreviousChannel(void) const
MythMediaBuffer * m_buffer
bool GetPlayingInfoMap(InfoMap &infoMap) const
void SetInitialTVState(bool islivetv)
determine initial tv state and playgroup for the recording
void ChangeState(TVState newState)
Puts a state change on the nextState queue.
std::chrono::minutes m_jumptime
QString PopPreviousChannel(void)
MythDeque< TVState > m_nextState
uint GetCardID(void) const
bool IsSameProgram(const ProgramInfo &p) const
std::chrono::seconds m_playingLen
Initial CalculateLength()
MythTimer m_lastSignalUIInfoTime
void TeardownPlayer(void)
void UnlockPlayingInfo(const char *file, int line) const
ProgramInfo * m_pseudoLiveTVRec
void StopPlaying(void) const
ProgramInfo * m_playingInfo
Currently playing info.
Holds information on recordings and videos.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
QString GetBasename(void) const
bool HasPathname(void) const
static bool ExtractKey(const QString &uniquekey, uint &chanid, QDateTime &recstartts)
Extracts chanid and recstartts from a unique key generated by MakeUniqueKey().
bool QueryIsInUse(QStringList &byWho) const
Returns true if Program is in use.
bool IsVideoFile(void) const
QString toString(Verbosity v=kLongDescription, const QString &sep=":", const QString &grp="\"") const
bool IsVideoDVD(void) const
void SetIgnoreProgStart(bool ignore)
If "ignore" is true QueryProgStart() will return 0, otherwise QueryProgStart() will return the progst...
AutoExpireType QueryAutoExpire(void) const
Returns "autoexpire" field from "recorded" table.
void SetIgnoreBookmark(bool ignore)
If "ignore" is true GetBookmark() will return 0, otherwise GetBookmark() will return the bookmark pos...
uint GetEpisode(void) const
QString GetProgramID(void) const
QString GetRecordingGroup(void) const
void SaveAutoExpire(AutoExpireType autoExpire, bool updateDelete=false)
Set "autoexpire" field in "recorded" table to "autoExpire".
uint GetRecordingID(void) const
bool QueryIsDeleteCandidate(bool one_playback_allowed=false) const
Returns true iff this is a recording, it is not in use (except by the recorder), and at most one play...
int64_t QueryTotalFrames(void) const
If present in recording this loads total frames of the main video stream from database's stream marku...
bool IsFileReadable(void)
Attempts to ascertain if the main file for this ProgramInfo is readable.
void SetIgnoreLastPlayPos(bool ignore)
If "ignore" is true QueryLastPlayPos() will return 0, otherwise QueryLastPlayPos() will return the la...
QString GetHostname(void) const
bool IsRecording(void) const
uint GetSourceID(void) const
QString GetPlaybackGroup(void) const
QString GetTitle(void) const
bool QueryIsEditing(void) const
Queries "recorded" table for its "editing" field and returns true if it is set to true.
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
void SaveLastPlayPos(uint64_t frame)
TODO Move to RecordingInfo.
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
void SaveTotalFrames(int64_t frames)
Store the Total Frames at frame 0 in the recordedmarkup table.
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
QString GetSortTitle(void) const
bool IsVideoBD(void) const
virtual void ToMap(InfoMap &progMap, bool showrerecord=false, uint star_range=10, uint date_format=0) const
Converts ProgramInfo into QString QHash containing each field in ProgramInfo converted into localized...
QString GetPathname(void) const
QDate GetOriginalAirDate(void) const
void SaveEditing(bool edit)
Sets "editing" field in "recorded" table to "edit".
void ToStringList(QStringList &list) const
Serializes ProgramInfo into a QStringList which can be passed over a socket.
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
QString GetSubtitle(void) const
uint GetSeason(void) const
QString GetChannelSchedulingID(void) const
This is the unique programming identifier of a channel.
Holds information on a TV Program one might wish to record.
void QuickRecord(void)
Create a kSingleRecord if not already scheduled.
void ApplyRecordRecGroupChange(const QString &newrecgroup)
Sets the recording group, both in this RecordingInfo and in the database.
void ApplyTranscoderProfileChange(const QString &profile) const
Sets the transcoder profile for a recording.
Internal representation of a recording rule, mirrors the record table.
bool LoadTemplate(const QString &title, const QString &category="Default", const QString &categoryType="Default")
General purpose reference counter.
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
QAtomicInt m_referenceCount
virtual int IncrRef(void)
Increments reference count.
std::chrono::milliseconds SetSignalMonitoringRate(std::chrono::milliseconds rate, int notifyFrontend=1)
Sets the signal monitoring rate.
void StopLiveTV(void)
Tells TVRec to stop a "Live TV" recorder.
bool ShouldSwitchToAnotherCard(const QString &channelid)
Checks if named channel exists on current tuner, or another tuner.
void SpawnLiveTV(const QString &chainid, bool pip, const QString &startchan)
Tells TVRec to Spawn a "Live TV" recorder.
void ChangeChannel(int channeldirection)
void SetLiveRecording(bool recording)
int ChangePictureAttribute(PictureAdjustType type, PictureAttribute attr, bool up)
Changes brightness/contrast/colour/hue of a recording.
int GetPictureAttribute(PictureAttribute attr)
bool IsValidRecorder(void) const
void GetChannelInfo(InfoMap &infoMap, uint chanid=0)
bool CheckChannelPrefix(const QString &prefix, uint &complete_valid_channel_on_rec, bool &is_extra_char_useful, QString &needed_spacer)
Checks a prefix against the channels in the DB.
void PauseRecorder(void)
Tells TVRec to pause a recorder, used for channel and input changes.
void SetChannel(const QString &channel)
uint GetSignalLockTimeout(const QString &input)
bool SetChannelInfo(const InfoMap &infoMap)
bool CheckChannel(const QString &channel)
Checks if named channel exists on current tuner.
void CancelNextRecording(bool cancel)
int GetRecorderNumber(void) const
void ToggleChannelFavorite(const QString &changroupname)
bool IsRecording(bool *ok=nullptr)
static bool IsExiting(void)
static bool AllGood(const SignalMonitorList &slist)
Returns true if all the values in the list return true on IsGood().
static SignalMonitorList Parse(const QStringList &slist)
Converts a list of strings to SignalMonitorValue classes.
static QString GetSourceName(uint sourceid)
void BrowseEnd(bool ChangeChannel)
Ends channel browsing.
BrowseInfo GetBrowsedInfo() const
void BrowseDispInfo(const BrowseInfo &Browseinfo)
void BrowseChannel(const QString &Channum)
void BrowseInit(std::chrono::seconds BrowseMaxForward, bool BrowseAllTuners, bool UseChannelGroups, const QString &DBChannelOrdering)
uint GetBrowseChanId(const QString &Channum, uint PrefCardid, uint PrefSourceid) const
Returns a chanid for the channum, or 0 if none is available.
bool BrowseStart(bool SkipBrowse=false)
Begins channel browsing.
void ChangeAspectOverride(AspectOverrideMode AspectMode=kAspect_Toggle)
void GoToDVDProgram(bool Direction)
MythAudioState m_audioState
void SetCaptionsEnabled(bool Enable, bool UpdateOSD=true)
void ChangeZoom(ZoomDirection Zoom)
void GoToMenu(const QString &Menu)
void DisableEdit(int HowToSave)
void EnableCaptions(uint Mode, bool UpdateOSD=true)
void ChangeCaptionTrack(int Direction)
void UpdateLastPlayPosition(uint64_t frame)
void ChangeMuteState(bool CycleChannels=false)
void HideAll(bool KeepSubs=true, MythScreenType *Except=nullptr, bool DropNotification=false)
void ResizeScreenForVideo(QSize Size={})
void DisableCaptions(uint Mode, bool UpdateOSD=true)
void EmbedPlayback(bool Embed, const QRect &Rect={})
void UpdateBookmark(bool Clear=false)
void ChangeOSDMessage(const QString &Message)
void ChangeStereoOverride(StereoscopicMode Mode)
void ChangeOSDDialog(const MythOSDDialogData &Data)
void AdjustSubtitleDelay(std::chrono::milliseconds Delta)
void InitialisePlayerState()
void RefreshEditorState(bool CheckSaved=false)
void AdjustSubtitleZoom(int Delta)
MythOverlayState m_overlayState
void ChangeAdjustFill(AdjustFillMode FillMode=kAdjustFill_Toggle)
void WindowResized(const QSize &Size)
MythCaptionsState m_captionsState
void ChangeOSDPositionUpdates(bool Enable)
void ToggleDetectLetterBox()
void ChangeTrack(uint Type, int Direction)
void SetTeletextPage(uint Page)
void RequestEmbedding(bool Embed, const QRect &Rect={}, const QStringList &Data={})
MythVisualiserState m_visualiserState
void HandleTeletextAction(const QString &Action, bool &Handled)
void RestartITV(uint Chanid, uint Cardid, bool IsLiveTV)
void PauseAudioUntilReady()
void ToggleMoveBottomLine()
void HandleITVAction(const QString &Action, bool &Handled)
void EnableTeletext(int Page=0x100)
MythVideoColourState m_videoColourState
void ChangeVolume(bool Direction, int Volume)
void ToggleCaptionsByType(uint Type)
MythVideoBoundsState m_videoBoundsState
void IsOSDVisible(bool &Visible)
void ChangeAudioOffset(std::chrono::milliseconds Delta, std::chrono::milliseconds Value=-9999ms)
void ChangeAllowForcedSubtitles(bool Allow)
void ChangePictureAttribute(PictureAttribute Attribute, bool Direction, int Value)
void EnableVisualiser(bool Enable, bool Toggle=false, const QString &Name=QString())
void ChangeUpmix(bool Enable, bool Toggle=false)
MythEditorState m_editorState
void ChangeOSDText(const QString &Window, const InfoMap &Map, OSDTimeout Timeout)
void SetTrack(uint Type, uint TrackNo)
This is the coordinating class of the Recorder Subsystem.
std::chrono::milliseconds milliseconds
SleepTimerInfo(QString String, std::chrono::milliseconds MilliSeconds)
QList< std::chrono::seconds > m_tvmChapterTimes
void ChannelEditXDSFill(InfoMap &Info)
void DoQueueTranscode(const QString &Profile)
void HandleOSDIdle(const QString &Action)
MythTVMenu m_playbackCompactMenu
bool SubtitleZoomHandleAction(const QStringList &Actions)
void VolumeChange(bool Up, int NewVolume=-1)
bool ManualZoomHandleAction(const QStringList &Actions)
PictureAttribute m_adjustingPictureAttribute
Picture attribute to modify (on arrow left or right)
static bool IsTVRunning()
Check whether media is currently playing.
volatile int m_endOfRecPromptTimerId
void ShowLCDChannelInfo()
bool HandleLCDTimerEvent()
void GetPlayerWriteLock() const
void ProcessNetworkControlCommand(const QString &Command)
InfoMap m_chanEditMap
Channel Editing initial map.
bool m_requestDelete
User wants last video deleted.
QList< QKeyEvent * > m_screenPressKeyMapLiveTV
QString GetTitleName(int Title)
int Playback(const ProgramInfo &ProgInfo)
bool GetJumpToProgram() const
This is set if the user asked MythTV to jump to the previous recording in the playlist.
volatile int m_endOfPlaybackTimerId
static const int kInitFFRWSpeed
bool TranslateKeyPressOrGesture(const QString &Context, QEvent *Event, QStringList &Actions, bool IsLiveTV, bool AllowJumps=true)
volatile int m_networkControlTimerId
QList< QKeyEvent * > m_screenPressKeyMapPlayback
bool HandleOSDCutpoint(const QString &Action)
bool DoPlayerSeekToFrame(uint64_t FrameNum)
void ShowOSDAlreadyEditing()
static QList< QKeyEvent * > ConvertScreenPressKeyMap(const QString &KeyList)
void PopPreviousChannel(bool ImmediateChange)
PlayerContext m_playerContext
static const std::chrono::milliseconds kSpeedChangeCheckFrequency
static const std::chrono::milliseconds kEndOfRecPromptCheckFrequency
void HandleStateChange()
Changes the state to the state on the front of the state change queue.
static void ToggleChannelFavorite()
static const std::chrono::milliseconds kErrorRecoveryCheckFrequency
bool MenuItemDisplayPlayback(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu)
int StartTimer(std::chrono::milliseconds Interval, int Line)
static const std::vector< SleepTimerInfo > s_sleepTimes
uint GetQueuedChanID() const
bool m_underNetworkControl
initial show started via by the network control interface
void SleepDialogTimeout()
std::chrono::milliseconds m_dbIdleTimeout
QString m_dbChannelFormat
QMap< QString, ProgramList > m_progLists
bool AudioSyncHandleAction(const QStringList &Actions)
void DoEditSchedule(int EditType=kScheduleProgramGuide, const QString &EditArg="")
bool MenuItemDisplay(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu) override
bool m_ignoreKeyPresses
should we ignore keypresses
volatile int m_lcdVolumeTimerId
void ShowOSDStopWatchingRecording()
static const std::chrono::milliseconds kSleepTimerDialogTimeout
void UpdateOSDStatus(const QString &Title, const QString &Desc, const QString &Value, int Type, const QString &Units, int Position=0, enum OSDTimeout Timeout=kOSDTimeout_Med)
uint m_queuedChanID
Queued ChanID (from EPG channel selector)
int m_sleepDialogTimerId
Timer for sleep dialog.
bool m_subtitleDelayAdjustment
True if subtitle delay is turned on.
MythDeque< QString > m_networkControlCommands
void RetrieveCast(const ProgramInfo &ProgInfo)
void HandleSaveLastPlayPosEvent()
MythTVMenu m_cutlistCompactMenu
uint m_initialChanID
Initial chanid override for Live TV.
void PlaybackLoop()
The main playback loop.
static EMBEDRETURNVOIDSCHEDIT RunScheduleEditorPtr
bool m_sigMonMode
Are we in signal monitoring mode?
bool HasQueuedChannel() const
void ClearInputQueues(bool Hideosd)
Clear channel key buffer of input keys.
static bool IsPaused()
Check whether playback is paused.
bool m_savedPause
saved pause state before embedding
bool GetAllowRerecord() const
Returns true if the user told Mythtv to allow re-recording of the show.
QVector< string_pair > m_guests
bool m_allowRerecord
User wants to rerecord the last video if deleted.
ChannelGroupList m_dbChannelGroups
QString GetRecordingGroup() const
void setUnderNetworkControl(bool setting)
void HandleEndOfRecordingExitPromptTimerEvent()
static EMBEDRETURNVOIDEPG RunProgramGuidePtr
static void SetFuncPtr(const char *Name, void *Pointer)
Import pointers to functions used to embed the TV window into other containers e.g.
bool GetEndOfRecording() const
This is set to true if the player reaches the end of the recording without the user explicitly exitin...
QString GetAngleName(int Angle)
bool ProcessKeypressOrGesture(QEvent *Event)
float DoTogglePauseStart()
MThreadPool * GetPosThreadPool()
void DoSwitchAngle(int Angle)
QVariant m_tvmJumprecBackHack
bool RequestNextRecorder(bool ShowDialogs, const ChannelInfoList &Selection=ChannelInfoList())
bool HandleJumpToProgramAction(const QStringList &Actions)
void FillOSDMenuJumpRec(const QString &Category="", int Level=0, const QString &Selected="")
static const std::chrono::milliseconds kVideoExitDialogTimeout
MThreadPool * m_posThreadPool
void SwitchInputs(uint ChanID=0, QString ChanNum="", uint InputID=0)
QMap< QString, AskProgramInfo > m_askAllowPrograms
QString m_queuedChanNum
Input key presses queued up so far to form a valid ChanNum.
bool DoPlayerSeek(float Time)
bool m_stretchAdjustment
True if time stretch is turned on.
void FillOSDMenuActorShows(const QString &actor, int person_id, const QString &category="")
bool m_asInputMode
Are we in Arbitrary seek input mode?
bool StartPlayer(TVState desiredState)
PictureAdjustType m_adjustingPicture
Picture attribute type to modify.
QString GetQueuedInput() const
static const uint kNextSource
void PlaybackMenuDeinit(const MythTVMenu &Menu)
bool LiveTV(bool ShowDialogs, const ChannelInfoList &Selection)
Starts LiveTV.
PlayerContext * GetPlayerContext()
Return a pointer to TV::m_playerContext.
bool m_subtitleZoomAdjustment
True if subtitle zoom is turned on.
volatile int m_videoExitDialogTimerId
std::chrono::milliseconds m_sleepTimerTimeout
Current sleep timeout in msec.
void ShowOSDPromptDeleteRecording(const QString &Title, bool Force=false)
void DoTogglePauseFinish(float Time, bool ShowOSD)
void DoJumpChapter(int Chapter)
void HandleEndOfPlaybackTimerEvent()
void UpdateOSDSignal(const QStringList &List)
Updates Signal portion of OSD...
bool MenuItemDisplayCutlist(const MythTVMenuItemContext &Context, MythOSDDialogData *Menu)
bool HandleOSDVideoExit(const QString &Action)
bool m_dbRememberLastChannelGroup
void HandleOSDAskAllow(const QString &Action)
volatile int m_speedChangeTimerId
bool m_ccInputMode
Are we in CC/Teletext page/stream selection mode?
void UpdateOSDTimeoutMessage()
void ForceNextStateNone()
void PauseLiveTV()
Used in ChangeChannel() to temporarily stop video output.
static EMBEDRETURNVOID RunPlaybackBoxPtr
void ShowOSDIdle()
After idleTimer has expired, display a dialogue warning the user that we will exit LiveTV unless they...
void GetPlayerReadLock() const
int m_tvmCurtrack[kTrackTypeCount]
MythTimer m_keyRepeatTimer
Queue of unprocessed key presses.
void StartOsdNavigation()
static const std::chrono::milliseconds kEndOfPlaybackFirstCheckTimer
static const uint kPreviousSource
void HandleOSDAlreadyEditing(const QString &Action, bool WasPaused)
static EMBEDRETURNVOIDFINDER RunProgramFinderPtr
volatile int m_lcdTimerId
volatile int m_channelGroupId
QRect m_playerBounds
Prior GUI window bounds, for DoEditSchedule() and player exit().
QReadWriteLock m_playerLock
lock on player and playerActive changes
bool m_wantsToQuit
True if the user told MythTV to stop playback.
QRecursiveMutex m_askAllowLock
void PlaybackExiting(TV *Player)
void onApplicationStateChange(Qt::ApplicationState State)
bool DialogIsVisible(const QString &Dialog)
void UpdateOSDProgInfo(const char *WhichInfo)
Update and display the passed OSD set with programinfo.
static const uint kInputKeysMax
static bool StateIsLiveTV(TVState State)
bool StartRecorder(std::chrono::milliseconds MaxWait=-1ms)
Starts recorder, must be called before StartPlayer().
bool CreatePlayer(TVState State, bool Muted=false)
static bool StartTV(ProgramInfo *TVRec, uint Flags, const ChannelInfoList &Selection=ChannelInfoList())
Start playback of media.
void MenuLazyInit(void *Field)
volatile int m_asInputTimerId
bool event(QEvent *Event) override
This handles all standard events.
bool DoSetPauseState(bool Pause)
bool HandleTrackAction(const QString &Action)
static const int kScreenPressRegionCount
screen area to keypress translation region is now 0..11 0 1 2 3 4 5 6 7 8 9 10 11
void HandleLCDVolumeTimerEvent()
static bool IsTunable(uint ChanId)
void HandleOSDSleep(const QString &Action)
void HandlePseudoLiveTVTimerEvent()
bool m_audiosyncAdjustment
True if audiosync is turned on.
volatile int m_exitPlayerTimerId
bool m_savePosOnExit
False until first timer event.
QString GetQueuedChanNum() const
bool ProcessSmartChannel(QString &InputStr)
void StartChannelEditMode()
Starts channel editing mode.
static QStringList lastProgramStringList
void GetChapterTimes(QList< std::chrono::seconds > &Times)
bool TranslateGesture(const QString &Context, MythGestureEvent *Event, QStringList &Actions, bool IsLiveTV)
static bool StateIsPlaying(TVState State)
void StartProgramEditMode()
Starts Program Cut Map Editing mode.
bool SubtitleDelayHandleAction(const QStringList &Actions)
int GetQueuedInputAsInt(bool *OK=nullptr, int Base=10) const
int m_dbPlaybackExitPrompt
static void MenuStrings()
bool BrowseHandleAction(const QStringList &Actions)
void DoSkipCommercials(int Direction)
static TV * AcquireRelease(int &RefCount, bool Acquire, bool Create=false)
Statically create, destroy or check the existence of the TV instance.
void DoTogglePictureAttribute(PictureAdjustType Type)
bool ContextIsPaused(const char *File, int Location)
void ToggleOSD(bool IncludeStatusOSD)
Cycle through the available Info OSDs.
volatile int m_saveLastPlayPosTimerId
volatile int m_ccInputTimerId
bool HandleOSDChannelEdit(const QString &Action)
Processes channel editing key.
QMutex m_channelGroupLock
Lock necessary when modifying channel group variables.
void UnpauseLiveTV(bool Quietly=false)
Used in ChangeChannel() to restart video output.
void ReturnPlayerLock() const
std::vector< int > m_ffRewSpeeds
TvPlayWindow * m_myWindow
Our screen, if it exists.
void HandleOSDClosed(int OSDType)
bool eventFilter(QObject *Object, QEvent *Event) override
Prevent events from being sent to another object.
static bool StateIsRecording(TVState State)
void ShowOSDCutpoint(const QString &Type)
void DoArbSeek(ArbSeekWhence Whence, bool HonorCutlist)
void ReturnOSDLock() const
void SetBookmark(bool Clear=false)
PictureAttribute NextPictureAdjustType(PictureAdjustType Type, PictureAttribute Attr)
bool m_weDisabledGUI
true if this instance disabled MythUI drawing.
void UpdateOSDSeekMessage(const QString &Msg, enum OSDTimeout Timeout)
bool SeekHandleAction(const QStringList &Actions, bool IsDVD)
volatile int m_errorRecoveryTimerId
void PlaybackMenuShow(const MythTVMenu &Menu, const QDomNode &Node, const QDomNode &Selected)
void OSDDialogEvent(int Result, const QString &Text, QString Action)
void HandleVideoExitDialogTimerEvent()
void SetAutoCommercialSkip(CommSkipMode SkipMode=kCommSkipOff)
static const std::chrono::milliseconds kIdleTimerDialogTimeout
void HideOSDWindow(const char *window)
static const std::chrono::milliseconds kSaveLastPlayPosTimeout
bool m_dbEndOfRecExitPrompt
void AskAllowRecording(const QStringList &Msg, int Timeuntil, bool HasRec, bool HasLater)
void ShowPreviousChannel()
void UpdateChannelList(int GroupID)
update the channel list with channels from the selected channel group
static EMBEDRETURNVOIDPROGLIST RunProgramListPtr
void SetExitPlayer(bool SetIt, bool WantsTo)
bool m_dbContinueEmbedded
void ChangeTimeStretch(int Dir, bool AllowEdit=true)
bool TimeStretchHandleAction(const QStringList &Actions)
static const std::chrono::milliseconds kEndOfPlaybackCheckFrequency
static EMBEDRETURNVOID RunViewScheduledPtr
QStringList m_tvmTracks[kTrackTypeCount]
bool FFRewHandleAction(const QStringList &Actions)
static int ConfiguredTunerCards()
If any cards are configured, return the number.
void ChannelEditAutoFill(InfoMap &Info)
Automatically fills in as much information as possible.
void SwitchSource(uint Direction)
void SetSpeedChangeTimer(std::chrono::milliseconds When, int Line)
void HandleOSDInfo(const QString &Action)
void AddKeyToInputQueue(char Key)
bool ActivePostQHandleAction(const QStringList &Actions)
int m_tvmFreeRecorderCount
QDateTime m_lastLockSeenTime
void DoSeekAbsolute(long long Seconds, bool HonorCutlist)
bool ActiveHandleAction(const QStringList &Actions, bool IsDVD, bool IsDVDStillFrame)
static const std::chrono::milliseconds kInputModeTimeout
void timerEvent(QTimerEvent *Event) override
MythMainWindow * m_mainWindow
QString m_queuedInput
Input key presses queued up so far...
ProgramInfo * m_lastProgram
last program played with this player
static QVector< uint > IsTunableOn(PlayerContext *Context, uint ChanId)
void DoTogglePause(bool ShowOSD)
bool IsSameProgram(const ProgramInfo *ProgInfo) const
MythTVMenu m_playbackMenu
void ScheduleStateChange()
volatile int m_signalMonitorTimerId
void OverrideScan(FrameScanType Scan)
QVector< string_pair > m_guest_stars
void DoSwitchTitle(int Title)
void EditSchedule(int EditType=kScheduleProgramGuide, const QString &arg="")
int m_sleepTimerId
Timer for turning off playback.
void ChangeChannel(const ChannelInfoList &Options)
bool DiscMenuHandleAction(const QStringList &Actions) const
bool IsTunablePriv(uint ChanId)
uint m_dbAutoexpireDefault
uint m_sleepIndex
Index into sleep_times.
RemoteEncoder * m_switchToRec
Main recorder to use after a successful SwitchCards() call.
CommSkipMode m_tvmCurSkip
void ChangeFFRew(int Direction)
void ITVRestart(bool IsLive)
Restart the MHEG/MHP engine.
void SetManualZoom(bool ZoomON, const QString &Desc)
QElapsedTimer m_lockTimer
bool ToggleHandleAction(const QStringList &Actions, bool IsDVD)
bool m_endOfRecording
!player->IsPlaying() && StateIsPlaying()
void SetLastProgram(const ProgramInfo *ProgInfo)
QRecursiveMutex m_chanEditMapLock
Lock for chanEditMap and ddMap.
static const std::chrono::milliseconds kKeyRepeatTimeout
std::chrono::seconds GetTitleDuration(int Title)
void PrepareToExitPlayer(int Line)
void ShowNoRecorderDialog(NoRecorderMsg MsgType=kNoRecorders)
static void FillOSDMenuCastButton(MythOSDDialogData &dialog, const QVector< string_pair > &people)
bool HasQueuedInput() const
bool PictureAttributeHandleAction(const QStringList &Actions)
ProgramInfo * GetLastProgram() const
QVector< string_pair > m_actors
int m_idleDialogTimerId
Timer for idle dialog.
void Embed(bool Embed, QRect Rect={}, const QStringList &Data={})
void PrepToSwitchToRecordedProgram(const ProgramInfo &ProgInfo)
bool m_inPlaylist
show is part of a playlist
bool StartPlaying(std::chrono::milliseconds MaxWait=-1ms)
void HandleSpeedChangeTimerEvent()
void SetInPlayList(bool InPlayList)
bool Init()
Performs instance initialization, returns true on success.
void StopStuff(bool StopRingBuffer, bool StopPlayer, bool StopRecorder)
Can shut down the ringbuffers, the players, and in LiveTV it can shut down the recorders.
volatile int m_pseudoChangeChanTimerId
void FillOSDMenuCast(void)
bool m_dbUseChannelGroups
void customEvent(QEvent *Event) override
This handles all custom events.
volatile int m_queueInputTimerId
void ScheduleInputChange()
int m_idleTimerId
Timer for turning off playback after idle period.
void DoSeek(float Time, const QString &Msg, bool TimeIsOffset, bool HonorCutlist)
static const std::chrono::milliseconds kLCDTimeout
bool m_clearPosOnExit
False unless requested by user on playback exit.
const MythTVMenu & getMenuFromId(MenuTypeId id)
void ChangeSpeed(int Direction)
void ShowOSDMenu(bool isCompact=false)
ChannelInfoList m_channelGroupChannelList
void PlaybackMenuInit(const MythTVMenu &Menu)
bool CalcPlayerSliderPosition(osdInfo &info, bool paddedFields=false) const
Simple screen shown while the video player is starting up.
void UpdateProgress(void)
bool Create(void) override
static uint Parse(const QString &vbiformat)
int to_track_type(const QString &str)
@ kTrackTypeTeletextCaptions
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::milliseconds > millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static void showStatus(void)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythNotificationCenter * GetNotificationCenter(void)
MythMainWindow * GetMythMainWindow(void)
static QString GET_KEY(const QString &Context, const QString &Action)
static void REG_KEY(const QString &Context, const QString &Action, const QString &Description, const QString &Key)
void ShowNotificationError(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
convenience utility to display error message as notification
void SendMythSystemPlayEvent(const QString &msg, const ProgramInfo *pginfo)
static MythThemedMenu * menu
StereoscopicMode ActionToStereoscopic(const QString &Action)
bool IsActionable(const QString &Action, const QStringList &Actions)
QHash< QString, QString > InfoMap
static constexpr const char * ACTION_SCREENSHOT
static constexpr const char * ACTION_LEFT
static constexpr const char * ACTION_DOWN
static constexpr const char * ACTION_TVPOWERON
static constexpr const char * ACTION_TVPOWEROFF
static constexpr const char * ACTION_RIGHT
static constexpr const char * ACTION_SELECT
static constexpr const char * ACTION_UP
static constexpr const char * ACTION_GETSTATUS
QString formatTime(std::chrono::milliseconds msecs, QString fmt)
Format a milliseconds time value.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
std::chrono::seconds secsInFuture(const QDateTime &future)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
MBASE_PUBLIC int naturalCompare(const QString &_a, const QString &_b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
This method chops the input a and b into pieces of digits and non-digits (a1.05 becomes a | 1 | .
def scan(profile, smoonURL, gate)
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
static constexpr const char * OSD_WIN_BROWSE
static constexpr const char * OSD_DLG_EDITOR
static constexpr const char * OSD_DLG_INFO
static constexpr const char * OSD_WIN_PROGINFO
static constexpr const char * OSD_WIN_STATUS
@ kOSDFunctionalType_SubtitleZoomAdjust
@ kOSDFunctionalType_AudioSyncAdjust
@ kOSDFunctionalType_SubtitleDelayAdjust
@ kOSDFunctionalType_SmartForward
@ kOSDFunctionalType_Default
@ kOSDFunctionalType_TimeStretchAdjust
@ kOSDFunctionalType_PictureAdjust
static constexpr const char * OSD_DLG_SLEEP
static constexpr const char * OSD_DLG_CONFIRM
static constexpr const char * OSD_DLG_VIDEOEXIT
static constexpr const char * OSD_WIN_INPUT
static constexpr const char * OSD_DLG_CUTPOINT
static constexpr const char * OSD_DLG_EDITING
static constexpr const char * OSD_WIN_PROGEDIT
static constexpr const char * OSD_DLG_MENU
static constexpr const char * OSD_DLG_IDLE
static constexpr const char * OSD_DLG_ASKALLOW
static constexpr const char * OSD_DLG_NAVIGATE
static constexpr const char * OSD_WIN_MESSAGE
static constexpr const char * OSD_DLG_DELETE
std::deque< QString > StringDeque
const QString kPlayerInUseID
const QString kRecorderInUseID
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
static eu8 clamp(eu8 value, eu8 low, eu8 high)
std::vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
static void show(uint8_t *buf, int length)
std::vector< SignalMonitorValue > SignalMonitorList
QHash< QString, int > values
QString toTypeString(PictureAdjustType type)
QString StateToString(TVState state)
Returns a human readable QString representing a TVState.
QString toTitleString(PictureAdjustType type)
@ BROWSE_RIGHT
Fetch information on current channel in the future.
@ BROWSE_LEFT
Fetch information on current channel in the past.
@ BROWSE_UP
Fetch information on previous channel.
@ BROWSE_FAVORITE
Fetch information on the next favorite channel.
@ BROWSE_DOWN
Fetch information on next channel.
@ kAdjustingPicture_Playback
@ kAdjustingPicture_Recording
@ kAdjustingPicture_Channel
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
@ CHANNEL_DIRECTION_FAVORITE
TVState
TVState is an enumeration of the states used by TV and TVRec.
@ kState_WatchingDVD
Watching DVD is the state when we are watching a DVD.
@ kState_None
None State, this is the initial state in both TV and TVRec, it indicates that we are ready to change ...
@ kState_RecordingOnly
Recording Only is a TVRec only state for when we are recording a program, but there is no one current...
@ kState_WatchingLiveTV
Watching LiveTV is the state for when we are watching a recording and the user has control over the c...
@ kState_Error
Error State, if we ever try to enter this state errored is set.
@ kState_WatchingPreRecorded
Watching Pre-recorded is a TV only state for when we are watching a pre-existing recording.
@ kState_WatchingRecording
Watching Recording is the state for when we are watching an in progress recording,...
@ kState_WatchingBD
Watching BD is the state when we are watching a BD.
@ kState_ChangingState
This is a placeholder state which we never actually enter, but is returned by GetState() when we are ...
@ kState_WatchingVideo
Watching Video is the state when we are watching a video and is not a dvd or BD.
#define ACTION_TOGGLESUBS
#define ACTION_BOTTOMLINEMOVE
#define ACTION_TOGGLEEXTTEXT
#define ACTION_TOGGLEOSDDEBUG
#define ACTION_TOGGLEPGORDER
#define ACTION_ENABLEFORCEDSUBS
#define ACTION_TOGGLESLEEP
#define ACTION_NEXTSUBPAGE
#define ACTION_SWITCHANGLE
#define ACTION_DISABLEVISUALISATION
#define ACTION_JUMPTODVDCHAPTERMENU
#define ACTION_TOGGLESUBTITLEDELAY
#define ACTION_VIEWSCHEDULED
#define ACTION_ZOOMHORIZONTALIN
#define ACTION_TOGGELAUDIOSYNC
#define ACTION_ZOOMVERTICALIN
#define ACTION_TOGGLEVISUALISATION
#define ACTION_DISABLEEXTTEXT
#define ACTION_TOGGLEBACKGROUND
#define ACTION_ZOOMHORIZONTALOUT
#define ACTION_OSDNAVIGATION
#define ACTION_CHANNELSEARCH
#define ACTION_JUMPTODVDROOTMENU
#define ACTION_ENABLEEXTTEXT
#define ACTION_TOGGLERECORD
#define ACTION_SETCONTRAST
#define ACTION_LISTRECORDEDEPISODES
#define ACTION_BIGJUMPREW
#define ACTION_TOGGLECHANCONTROLS
#define ACTION_3DTOPANDBOTTOMDISCARD
#define ACTION_LOADCOMMSKIP
#define ACTION_SETBRIGHTNESS
#define ACTION_PREVSUBPAGE
#define ACTION_TOGGLESUBTITLEZOOM
#define ACTION_DISABLEUPMIX
#define ACTION_TOGGLEBOOKMARK
#define ACTION_ZOOMASPECTDOWN
#define ACTION_SWITCHTITLE
#define ACTION_3DSIDEBYSIDEDISCARD
#define ACTION_DISABLESUBS
#define ACTION_SEEKABSOLUTE
#define ACTION_JUMPTOPOPUPMENU
#define ACTION_ENABLESUBS
#define ACTION_PREVRECORDED
#define ACTION_BIGJUMPFWD
#define ACTION_JUMPCHAPTER
#define ACTION_EXITSHOWNOPROMPTS
#define ACTION_DISABLEFORCEDSUBS
#define ACTION_ZOOMASPECTUP
#define ACTION_MENUCOMPACT
#define ACTION_SETAUDIOSYNC
#define ACTION_ENABLEVISUALISATION
#define ACTION_ENABLEUPMIX
#define ACTION_TOGGLEUPMIX
#define ACTION_MENUYELLOW
#define ACTION_BOTTOMLINESAVE
#define ACTION_VOLUMEDOWN
#define ACTION_JUMPTODVDTITLEMENU
#define ACTION_TOGGLERECCONTROLS
#define ACTION_ZOOMVERTICALOUT
#define ACTION_SETBOOKMARK
#define ACTION_CHANNELDOWN
#define ACTION_ZOOMCOMMIT
static int comp_season_rev(const ProgramInfo *a, const ProgramInfo *b)
static QString add_spacer(const QString &chan, const QString &spacer)
#define BUTTON3(action, textActive, textInactive, isMenu)
#define BUTTON2(action, textActive, textInactive)
static void insert_map(InfoMap &infoMap, const InfoMap &newMap)
static bool comp_title(const ProgramInfo *a, const ProgramInfo *b)
static QString tv_i18n(const QString &msg)
static QString toCommaList(const QVector< uint > &list)
static uint get_chanid(const PlayerContext *ctx, uint cardid, const QString &channum)
#define BUTTON(action, text)
static int comp_originalAirDate_rev(const ProgramInfo *a, const ProgramInfo *b)
static bool SysEventHandleAction(MythMainWindow *MainWindow, QKeyEvent *e, const QStringList &actions)
#define TRANSITION(ASTATE, BSTATE)
void(*)(const ProgramInfo *, void *) EMBEDRETURNVOIDSCHEDIT
void(*)(void *, bool) EMBEDRETURNVOID
void(*)(uint, const QString &, const QDateTime, TV *, bool, bool, int) EMBEDRETURNVOIDEPG
void(*)(TV *, int, const QString &) EMBEDRETURNVOIDPROGLIST
void(*)(TV *, bool, bool) EMBEDRETURNVOIDFINDER
@ kStartTVIgnoreLastPlayPos
@ kStartTVIgnoreProgStart
@ kStartTVByNetworkCommand
NoRecorderMsg
Type of message displayed in ShowNoRecorderDialog()
@ kNoRecorders
No free recorders.
@ kNoCurrRec
No current recordings.
@ kNoTuners
No capture cards configured.
bool RemoteIsBusy(uint inputid, InputInfo &busy_input)
RemoteEncoder * RemoteGetExistingRecorder(const ProgramInfo *pginfo)
RemoteEncoder * RemoteRequestNextFreeRecorder(int inputid)
std::vector< InputInfo > RemoteRequestFreeInputInfo(uint excluded_input)
int RemoteGetFreeRecorderCount(void)
RemoteEncoder * RemoteRequestFreeRecorderFromList(const QStringList &qualifiedRecorders, uint excluded_input)
void RemoteCancelNextRecording(uint inputid, bool cancel)
PictureAttribute next_picattr(PictureAttributeSupported Supported, PictureAttribute Attribute)
QString GetZoomString(float HorizScale, float VertScale, QPoint Move)
@ kDisplayRawTextSubtitle
@ kDisplayNUVTeletextCaptions
@ kDisplayTeletextCaptions
@ kAdjustFill_AutoDetect_DefaultHalf
@ kAdjustFill_AutoDetect_DefaultOff
PictureAttributeSupported
@ kPictureAttributeSupported_Colour
@ kPictureAttributeSupported_Volume
@ kPictureAttributeSupported_Brightness
@ kPictureAttributeSupported_Hue
@ kPictureAttributeSupported_Contrast
@ kPictureAttributeSupported_None
@ kPictureAttribute_Range
@ kPictureAttribute_Contrast
@ kPictureAttribute_Brightness
@ kPictureAttribute_Volume
@ kPictureAttribute_Colour
QString ScanTypeToUserString(FrameScanType Scan, bool Forced=false)
@ kStereoscopicModeTopAndBottomDiscard
@ kStereoscopicModeSideBySideDiscard
@ kStereoscopicModeIgnore3D
PictureAttributeSupported toMask(PictureAttribute PictureAttribute)
bool OptionalCaptionEnabled(uint Captions)
Return whether any optional captions are enabled.