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);
126 query.
prepare(
"SELECT COUNT(cardid) FROM capturecard;");
128 count = query.
value(0).toInt();
130 LOG(VB_RECORD, LOG_INFO,
131 "ConfiguredTunerCards() = " + QString::number(count));
145 static QMutex s_lock;
146 static TV* s_tv =
nullptr;
147 QMutexLocker locker(&s_lock);
159 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Ref count error");
205 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Already have a player");
211 auto flags =
static_cast<PlayerFlags>(playerflags);
244 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
249 MaxWait = (MaxWait <= 0ms) ? 20s : MaxWait;
251 MaxWait = std::chrono::milliseconds::max();
261 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
262 QString(
"StartPlaying(): took %1 ms to start player.")
263 .arg(
t.elapsed().count()));
266 LOG(VB_GENERAL, LOG_ERR,
LOC +
"StartPlaying() Failed to start player");
298 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Already have a TV object.");
303 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
306 bool quitAll =
false;
307 bool showDialogs =
true;
308 bool playCompleted =
false;
310 bool startSysEventSent =
false;
311 bool startLivetvEventSent =
false;
324 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed initializing TV");
346 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- begin");
351 else if (!startSysEventSent)
353 startSysEventSent =
true;
357 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->Playback() -- end");
361 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- begin");
362 if (!tv->
LiveTV(showDialogs, Selection))
367 else if (!startSysEventSent)
369 startSysEventSent =
true;
370 startLivetvEventSent =
true;
374 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"tv->LiveTV() -- end");
379 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners configured");
381 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No tuners free for live tv");
392 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Entering main playback loop.");
394 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Exiting main playback loop.");
402 curProgram = nextProgram;
416 quitAll |= !playerError.isEmpty();
419 QCoreApplication::processEvents();
423 playCompleted =
true;
433 if (startSysEventSent)
441 list.push_back(allowrerecord ?
"1" :
"0");
442 MythEvent me(
"LOCAL_PBB_DELETE_RECORDINGS", list);
453 else if (startSysEventSent)
458 if (!playerError.isEmpty())
468 if (startLivetvEventSent)
471 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
473 return playCompleted;
483 if (name ==
"playbackbox")
485 else if (name ==
"viewscheduled")
487 else if (name ==
"programguide")
489 else if (name ==
"programfinder")
491 else if (name ==
"scheduleeditor")
493 else if (name ==
"programlist")
500 "Play Program"),
"P,Media Play");
502 "Stop Program"),
"");
504 "Toggle recording status of current program"),
"R");
506 "Page the program guide back one day"),
"Home,Media Previous");
508 "Page the program guide forward one day"),
"End,Media Next");
510 "Page the program guide left"),
",,<,Ctrl+B,Media Rewind");
512 "Page the program guide right"),
">,.,Ctrl+F,Media Fast Forward");
514 "Toggle the current channel as a favorite"),
"?");
516 "Reverse the channel order in the program guide"),
"");
518 "Show the Program Guide"),
"S");
520 "Show the Program Finder"),
"#");
522 "Show the Channel Search"),
"");
523 REG_KEY(
"TV Frontend",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
524 "Cycle through channel groups and all channels in the "
525 "program guide."),
"/");
526 REG_KEY(
"TV Frontend",
"CHANUPDATE", QT_TRANSLATE_NOOP(
"MythControls",
527 "Switch channels without exiting guide in Live TV mode."),
"X");
529 "Volume down"),
"[,{,F10,Volume Down");
531 "Volume up"),
"],},F11,Volume Up");
533 "Mute"),
"|,\\,F9,Volume Mute");
534 REG_KEY(
"TV Frontend",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
535 "Cycle audio channels"),
"");
536 REG_KEY(
"TV Frontend",
"RANKINC", QT_TRANSLATE_NOOP(
"MythControls",
537 "Increase program or channel rank"),
"Right");
538 REG_KEY(
"TV Frontend",
"RANKDEC", QT_TRANSLATE_NOOP(
"MythControls",
539 "Decrease program or channel rank"),
"Left");
540 REG_KEY(
"TV Frontend",
"UPCOMING", QT_TRANSLATE_NOOP(
"MythControls",
541 "List upcoming episodes"),
"O");
543 "List scheduled upcoming episodes"),
"");
545 "List previously recorded episodes"),
"");
546 REG_KEY(
"TV Frontend",
"DETAILS", QT_TRANSLATE_NOOP(
"MythControls",
547 "Show details"),
"U");
548 REG_KEY(
"TV Frontend",
"VIEWINPUT", QT_TRANSLATE_NOOP(
"MythControls",
549 "Switch Recording Input view"),
"C");
550 REG_KEY(
"TV Frontend",
"CUSTOMEDIT", QT_TRANSLATE_NOOP(
"MythControls",
551 "Edit Custom Record Rule"),
"");
552 REG_KEY(
"TV Frontend",
"CHANGERECGROUP", QT_TRANSLATE_NOOP(
"MythControls",
553 "Change Recording Group"),
"");
554 REG_KEY(
"TV Frontend",
"CHANGEGROUPVIEW", QT_TRANSLATE_NOOP(
"MythControls",
555 "Change Group View"),
"");
557 "List recorded episodes"),
"");
577 if (selectKeys !=
"?")
580 togBkmKeys = selectKeys;
582 bkmKeys = selectKeys;
586 "Add Bookmark"), bkmKeys);
588 "Toggle Bookmark"), togBkmKeys);
589 REG_KEY(
"TV Playback",
"BACK", QT_TRANSLATE_NOOP(
"MythControls",
590 "Exit or return to DVD menu"),
"Esc,Back");
592 "Playback Compact Menu"),
"Alt+M");
594 "Clear OSD"),
"Backspace");
596 "Pause"),
"P,Space,Media Play");
598 "Fast Forward"),
"Right");
602 "Arbitrary Seek"),
"*");
604 "Seek to a position in seconds"),
"");
606 "Channel up"),
"Up");
608 "Channel down"),
"Down");
609 REG_KEY(
"TV Playback",
"NEXTFAV", QT_TRANSLATE_NOOP(
"MythControls",
610 "Switch to the next favorite channel"),
"/");
611 REG_KEY(
"TV Playback",
"PREVCHAN", QT_TRANSLATE_NOOP(
"MythControls",
612 "Switch to the previous channel"),
"H");
614 "Jump ahead"),
"PgDown");
616 "Jump back"),
"PgUp");
617 REG_KEY(
"TV Playback",
"INFOWITHCUTLIST", QT_TRANSLATE_NOOP(
"MythControls",
618 "Info utilizing cutlist"),
"");
620 "Jump to bookmark"),
"K");
621 REG_KEY(
"TV Playback",
"FFWDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
622 "Fast Forward (Sticky) or Forward one second while paused"),
">,.,Ctrl+F,Media Fast Forward");
623 REG_KEY(
"TV Playback",
"RWNDSTICKY", QT_TRANSLATE_NOOP(
"MythControls",
624 "Rewind (Sticky) or Rewind one second while paused"),
",,<,Ctrl+B,Media Rewind");
625 REG_KEY(
"TV Playback",
"NEXTSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
626 "Next Video Source"),
"Y");
627 REG_KEY(
"TV Playback",
"PREVSOURCE", QT_TRANSLATE_NOOP(
"MythControls",
628 "Previous Video Source"),
"");
629 REG_KEY(
"TV Playback",
"NEXTINPUT", QT_TRANSLATE_NOOP(
"MythControls",
631 REG_KEY(
"TV Playback",
"NEXTCARD", QT_TRANSLATE_NOOP(
"MythControls",
633 REG_KEY(
"TV Playback",
"SKIPCOMMERCIAL", QT_TRANSLATE_NOOP(
"MythControls",
634 "Skip Commercial"),
"Z,End,Media Next");
635 REG_KEY(
"TV Playback",
"SKIPCOMMBACK", QT_TRANSLATE_NOOP(
"MythControls",
636 "Skip Commercial (Reverse)"),
"Q,Home,Media Previous");
638 "Jump to the start of the recording."),
"Ctrl+A");
639 REG_KEY(
"TV Playback",
"TOGGLEBROWSE", QT_TRANSLATE_NOOP(
"MythControls",
640 "Toggle channel browse mode"),
"O");
642 "Toggle recording status of current program"),
"R");
644 "Toggle the current channel as a favorite"),
"?");
646 "Volume down"),
"[,{,F10,Volume Down");
648 "Volume up"),
"],},F11,Volume Up");
650 "Mute"),
"|,\\,F9,Volume Mute");
652 "Set the volume"),
"");
653 REG_KEY(
"TV Playback",
"CYCLEAUDIOCHAN", QT_TRANSLATE_NOOP(
"MythControls",
654 "Cycle audio channels"),
"");
656 "Toggle audio upmixer"),
"Ctrl+U");
658 QT_TRANSLATE_NOOP(
"MythControls",
"Move BottomLine off screen"),
"L");
660 QT_TRANSLATE_NOOP(
"MythControls",
"Save manual zoom for BottomLine"),
"");
661 REG_KEY(
"TV Playback",
"TOGGLEASPECT", QT_TRANSLATE_NOOP(
"MythControls",
662 "Toggle the video aspect ratio"),
"Ctrl+W");
663 REG_KEY(
"TV Playback",
"TOGGLEFILL", QT_TRANSLATE_NOOP(
"MythControls",
664 "Next Preconfigured Zoom mode"),
"W");
666 "Toggle any captions"),
"T");
668 "Enable any captions"),
"");
670 "Disable any captions"),
"");
671 REG_KEY(
"TV Playback",
"TOGGLETTC", QT_TRANSLATE_NOOP(
"MythControls",
672 "Toggle Teletext Captions"),
"");
673 REG_KEY(
"TV Playback",
"TOGGLESUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
674 "Toggle Subtitles"),
"");
675 REG_KEY(
"TV Playback",
"TOGGLECC608", QT_TRANSLATE_NOOP(
"MythControls",
676 "Toggle VBI CC"),
"");
677 REG_KEY(
"TV Playback",
"TOGGLECC708", QT_TRANSLATE_NOOP(
"MythControls",
678 "Toggle ATSC CC"),
"");
679 REG_KEY(
"TV Playback",
"TOGGLETTM", QT_TRANSLATE_NOOP(
"MythControls",
680 "Toggle Teletext Menu"),
"");
682 "Toggle External Subtitles"),
"");
684 "Enable External Subtitles"),
"");
686 "Disable External Subtitles"),
"");
687 REG_KEY(
"TV Playback",
"TOGGLERAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
688 "Toggle Text Subtitles"),
"");
690 REG_KEY(
"TV Playback",
"SELECTAUDIO_0", QT_TRANSLATE_NOOP(
"MythControls",
691 "Play audio track 1"),
"");
692 REG_KEY(
"TV Playback",
"SELECTAUDIO_1", QT_TRANSLATE_NOOP(
"MythControls",
693 "Play audio track 2"),
"");
694 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_0",QT_TRANSLATE_NOOP(
"MythControls",
695 "Display subtitle 1"),
"");
696 REG_KEY(
"TV Playback",
"SELECTSUBTITLE_1",QT_TRANSLATE_NOOP(
"MythControls",
697 "Display subtitle 2"),
"");
698 REG_KEY(
"TV Playback",
"SELECTRAWTEXT_0",QT_TRANSLATE_NOOP(
"MythControls",
699 "Display Text Subtitle 1"),
"");
700 REG_KEY(
"TV Playback",
"SELECTCC608_0", QT_TRANSLATE_NOOP(
"MythControls",
701 "Display VBI CC1"),
"");
702 REG_KEY(
"TV Playback",
"SELECTCC608_1", QT_TRANSLATE_NOOP(
"MythControls",
703 "Display VBI CC2"),
"");
704 REG_KEY(
"TV Playback",
"SELECTCC608_2", QT_TRANSLATE_NOOP(
"MythControls",
705 "Display VBI CC3"),
"");
706 REG_KEY(
"TV Playback",
"SELECTCC608_3", QT_TRANSLATE_NOOP(
"MythControls",
707 "Display VBI CC4"),
"");
708 REG_KEY(
"TV Playback",
"SELECTCC708_0", QT_TRANSLATE_NOOP(
"MythControls",
709 "Display ATSC CC1"),
"");
710 REG_KEY(
"TV Playback",
"SELECTCC708_1", QT_TRANSLATE_NOOP(
"MythControls",
711 "Display ATSC CC2"),
"");
712 REG_KEY(
"TV Playback",
"SELECTCC708_2", QT_TRANSLATE_NOOP(
"MythControls",
713 "Display ATSC CC3"),
"");
714 REG_KEY(
"TV Playback",
"SELECTCC708_3", QT_TRANSLATE_NOOP(
"MythControls",
715 "Display ATSC CC4"),
"");
717 "Enable Forced Subtitles"),
"");
719 "Disable Forced Subtitles"),
"");
721 REG_KEY(
"TV Playback",
"NEXTAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
722 "Next audio track"),
"+");
723 REG_KEY(
"TV Playback",
"PREVAUDIO", QT_TRANSLATE_NOOP(
"MythControls",
724 "Previous audio track"),
"-");
725 REG_KEY(
"TV Playback",
"NEXTSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
726 "Next subtitle track"),
"");
727 REG_KEY(
"TV Playback",
"PREVSUBTITLE", QT_TRANSLATE_NOOP(
"MythControls",
728 "Previous subtitle track"),
"");
729 REG_KEY(
"TV Playback",
"NEXTRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
730 "Next Text track"),
"");
731 REG_KEY(
"TV Playback",
"PREVRAWTEXT", QT_TRANSLATE_NOOP(
"MythControls",
732 "Previous Text track"),
"");
733 REG_KEY(
"TV Playback",
"NEXTCC608", QT_TRANSLATE_NOOP(
"MythControls",
734 "Next VBI CC track"),
"");
735 REG_KEY(
"TV Playback",
"PREVCC608", QT_TRANSLATE_NOOP(
"MythControls",
736 "Previous VBI CC track"),
"");
737 REG_KEY(
"TV Playback",
"NEXTCC708", QT_TRANSLATE_NOOP(
"MythControls",
738 "Next ATSC CC track"),
"");
739 REG_KEY(
"TV Playback",
"PREVCC708", QT_TRANSLATE_NOOP(
"MythControls",
740 "Previous ATSC CC track"),
"");
741 REG_KEY(
"TV Playback",
"NEXTCC", QT_TRANSLATE_NOOP(
"MythControls",
742 "Next of any captions"),
"");
744 REG_KEY(
"TV Playback",
"NEXTSCAN", QT_TRANSLATE_NOOP(
"MythControls",
745 "Next video scan overidemode"),
"");
746 REG_KEY(
"TV Playback",
"QUEUETRANSCODE", QT_TRANSLATE_NOOP(
"MythControls",
747 "Queue the current recording for transcoding"),
"X");
748 REG_KEY(
"TV Playback",
"SPEEDINC", QT_TRANSLATE_NOOP(
"MythControls",
749 "Increase the playback speed"),
"U");
750 REG_KEY(
"TV Playback",
"SPEEDDEC", QT_TRANSLATE_NOOP(
"MythControls",
751 "Decrease the playback speed"),
"J");
752 REG_KEY(
"TV Playback",
"ADJUSTSTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
753 "Turn on time stretch control"),
"A");
754 REG_KEY(
"TV Playback",
"STRETCHINC", QT_TRANSLATE_NOOP(
"MythControls",
755 "Increase time stretch speed"),
"");
756 REG_KEY(
"TV Playback",
"STRETCHDEC", QT_TRANSLATE_NOOP(
"MythControls",
757 "Decrease time stretch speed"),
"");
758 REG_KEY(
"TV Playback",
"TOGGLESTRETCH", QT_TRANSLATE_NOOP(
"MythControls",
759 "Toggle time stretch speed"),
"");
761 QT_TRANSLATE_NOOP(
"MythControls",
762 "Turn on audio sync adjustment controls"),
"");
764 QT_TRANSLATE_NOOP(
"MythControls",
765 "Set the audio sync adjustment"),
"");
766 REG_KEY(
"TV Playback",
"TOGGLEPICCONTROLS",
767 QT_TRANSLATE_NOOP(
"MythControls",
"Playback picture adjustments"),
770 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture brightness"),
"");
772 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture contrast"),
"");
774 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture color"),
"");
776 QT_TRANSLATE_NOOP(
"MythControls",
"Set the picture hue"),
"");
778 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
779 "for this channel"),
"Ctrl+G");
781 QT_TRANSLATE_NOOP(
"MythControls",
"Recording picture adjustments "
782 "for this recorder"),
"G");
783 REG_KEY(
"TV Playback",
"CYCLECOMMSKIPMODE",
784 QT_TRANSLATE_NOOP(
"MythControls",
"Cycle Commercial Skip mode"),
787 "Show the Program Guide"),
"S");
789 "Show the Program Finder"),
"#");
791 "Toggle the Sleep Timer"),
"F8");
795 "Jump to previously played recording"),
"");
797 "Display menu of recorded programs to jump to"),
"");
799 "Display scheduled recording list"),
"");
801 "Display previously recorded episodes"),
"");
803 "Monitor Signal Quality"),
"Alt+F7");
805 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Root Menu"),
"");
807 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the Popup Menu"),
"");
809 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Chapter Menu"),
"");
811 QT_TRANSLATE_NOOP(
"MythControls",
"Jump to the DVD Title Menu"),
"");
813 QT_TRANSLATE_NOOP(
"MythControls",
"Exit Show without any prompts"),
816 "Jump to a chapter"),
"");
818 "Switch title"),
"");
820 "Switch angle"),
"");
822 "OSD Navigation"),
"");
824 "Zoom mode - shift up"),
"");
826 "Zoom mode - shift down"),
"");
828 "Zoom mode - shift left"),
"");
830 "Zoom mode - shift right"),
"");
832 QT_TRANSLATE_NOOP(
"MythControls",
833 "Zoom mode - increase aspect ratio"),
"3");
835 QT_TRANSLATE_NOOP(
"MythControls",
836 "Zoom mode - decrease aspect ratio"),
"7");
838 "Zoom mode - zoom in"),
"9");
840 "Zoom mode - zoom out"),
"1");
842 QT_TRANSLATE_NOOP(
"MythControls",
843 "Zoom mode - vertical zoom in"),
"8");
845 QT_TRANSLATE_NOOP(
"MythControls",
846 "Zoom mode - vertical zoom out"),
"2");
848 QT_TRANSLATE_NOOP(
"MythControls",
849 "Zoom mode - horizontal zoom in"),
"6");
851 QT_TRANSLATE_NOOP(
"MythControls",
852 "Zoom mode - horizontal zoom out"),
"4");
854 "Zoom mode - quit and abandon changes"),
"");
856 "Zoom mode - commit changes"),
"");
859 "Display list of cast members"),
"");
865 "Menu Green"),
"F3");
867 "Menu Yellow"),
"F4");
879 "Clear editing cut points"),
"C,Q,Home");
881 "Invert Begin/End cut points"),
"I,Home Page");
885 "Load cuts from detected commercials"),
"Z,End");
887 "Jump to the next cut point"),
"PgDown,Media Next");
889 "Jump to the previous cut point"),
"PgUp,Media Previous");
891 "Jump back 10x the normal amount"),
",,<,Ctrl+B,Media Rewind");
893 "Jump forward 10x the normal amount"),
">,.,Ctrl+F,Media Fast Forward");
895 "Cut point editor compact menu"),
"Alt+M");
899 "Next Page"),
"Down");
901 "Previous Page"),
"Up");
903 "Next Subpage"),
"Right");
905 "Previous Subpage"),
"Left");
907 "Toggle Teletext"),
"T");
911 "Menu Green"),
"F3");
913 "Menu Yellow"),
"F4");
917 "Menu White"),
"F6");
919 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle Background"),
"F7");
921 "Reveal hidden Text"),
"F8");
925 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle audio visualisation"),
"");
929 QT_TRANSLATE_NOOP(
"MythControls",
"Toggle OSD playback information"),
"");
933 QT_TRANSLATE_NOOP(
"MythControls",
"Auto 3D"),
"");
935 QT_TRANSLATE_NOOP(
"MythControls",
"Ignore 3D"),
"");
937 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Side by Side"),
"");
939 QT_TRANSLATE_NOOP(
"MythControls",
"Discard 3D Top and Bottom"),
"");
993 { tr(
"Off",
"Sleep timer"), 0min },
994 { tr(
"30m",
"Sleep timer"), 30min },
995 { tr(
"1h",
"Sleep timer"), 60min },
996 { tr(
"1h30m",
"Sleep timer"), 90min },
997 { tr(
"2h",
"Sleep timer"), 120min }
1014 m_mainWindow(MainWindow),
1018 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Creating TV object");
1020 QObject::setObjectName(
"TV");
1037 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Finished creating TV object");
1042 QMap<QString,QString> kv;
1043 kv[
"LiveTVIdleTimeout"] =
"0";
1044 kv[
"BrowseMaxForward"] =
"240";
1045 kv[
"PlaybackExitPrompt"] =
"0";
1046 kv[
"AutomaticSetWatched"] =
"0";
1047 kv[
"EndOfRecordingExitPrompt"] =
"0";
1048 kv[
"JumpToProgramOSD"] =
"1";
1049 kv[
"GuiSizeForTV"] =
"0";
1050 kv[
"UseVideoModes"] =
"0";
1051 kv[
"JobsRunOnRecordHost"] =
"0";
1052 kv[
"ContinueEmbeddedTVPlay"] =
"0";
1053 kv[
"UseFixedWindowSize"] =
"1";
1054 kv[
"RunFrontendInWindow"] =
"0";
1055 kv[
"PersistentBrowseMode"] =
"0";
1056 kv[
"BrowseAllTuners"] =
"0";
1057 kv[
"ChannelOrdering"] =
"channum";
1059 kv[
"CustomFilters"] =
"";
1060 kv[
"ChannelFormat"] =
"<num> <sign>";
1062 kv[
"TryUnflaggedSkip"] =
"0";
1064 kv[
"ChannelGroupDefault"] =
"-1";
1065 kv[
"BrowseChannelGroup"] =
"0";
1066 kv[
"SmartForward"] =
"0";
1067 kv[
"FFRewReposTime"] =
"100";
1068 kv[
"FFRewReverse"] =
"1";
1070 kv[
"BrowseChannelGroup"] =
"0";
1071 kv[
"ChannelGroupDefault"] =
"-1";
1072 kv[
"ChannelGroupRememberLast"] =
"0";
1074 kv[
"VbiFormat"] =
"";
1075 kv[
"DecodeVBIFormat"] =
"";
1078 kv[
"PlaybackScreenPressKeyMap"] =
"P,Up,Z,],Left,Return,Return,Right,A,Down,Q,[";
1079 kv[
"LiveTVScreenPressKeyMap"] =
"P,Up,Z,S,Left,Return,Return,Right,A,Down,Q,F";
1081 constexpr std::array<const int,8> ff_rew_def { 3, 5, 10, 20, 30, 60, 120, 180 };
1082 for (
size_t i = 0; i < ff_rew_def.size(); i++)
1083 kv[QString(
"FFRewSpeed%1").arg(i)] = QString::number(ff_rew_def[i]);
1090 QString db_channel_ordering;
1092 m_dbIdleTimeout = std::chrono::minutes(kv[
"LiveTVIdleTimeout"].toUInt());
1093 auto db_browse_max_forward = std::chrono::minutes(kv[
"BrowseMaxForward"].toUInt());
1104 db_channel_ordering = kv[
"ChannelOrdering"];
1118 QString beVBI = kv[
"VbiFormat"];
1119 QString feVBI = kv[
"DecodeVBIFormat"];
1136 for (
size_t i = 0; i <
sizeof(ff_rew_def)/
sizeof(ff_rew_def[0]); i++)
1137 m_ffRewSpeeds.push_back(kv[QString(
"FFRewSpeed%1").arg(i)].toInt());
1154 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1158 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No MythMainWindow");
1179 fullscreen |= (0 == gui_width && 0 == gui_height);
1194 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created TvPlayWindow.");
1205 QCoreApplication::processEvents();
1230 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1236 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
1257 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"-- lock");
1290 lcd->setFunctionLEDs(
FUNC_TV,
false);
1292 lcd->switchToTime();
1308 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
1318 QCoreApplication::processEvents();
1394 .toUTC().toString(
"yyyy-MM-ddThh:mm:ssZ"));
1405 if (!
info.text[
"totalchapters"].isEmpty())
1407 QList<std::chrono::seconds> chapters;
1410 for (std::chrono::seconds chapter : std::as_const(chapters))
1411 var << QVariant((
long long)chapter.count());
1412 status.insert(
"chaptertimes", var);
1419 int currenttrack = -1;
1422 for (
int i = 0; i < list.size(); i++)
1424 if (i == currenttrack)
1425 status.insert(
"currentsubtitletrack", list[i]);
1426 tracks.insert(
"SELECTSUBTITLE_" + QString::number(i), list[i]);
1433 for (
int i = 0; i < list.size(); i++)
1435 if (i == currenttrack)
1436 status.insert(
"currentsubtitletrack", list[i]);
1437 tracks.insert(
"SELECTTTC_" + QString::number(i), list[i]);
1444 for (
int i = 0; i < list.size(); i++)
1446 if (i == currenttrack)
1447 status.insert(
"currentsubtitletrack", list[i]);
1448 tracks.insert(
"SELECTCC708_" + QString::number(i), list[i]);
1455 for (
int i = 0; i < list.size(); i++)
1457 if (i == currenttrack)
1458 status.insert(
"currentsubtitletrack", list[i]);
1459 tracks.insert(
"SELECTCC608_" + QString::number(i), list[i]);
1466 for (
int i = 0; i < list.size(); i++)
1468 if (i == currenttrack)
1469 status.insert(
"currentsubtitletrack", list[i]);
1470 tracks.insert(
"SELECTRAWTEXT_" + QString::number(i), list[i]);
1476 status.insert(
"currentsubtitletrack", tr(
"External Subtitles"));
1480 status.insert(
"totalsubtitletracks", tracks.size());
1481 if (!tracks.isEmpty())
1482 status.insert(
"subtitletracks", tracks);
1487 for (
int i = 0; i < list.size(); i++)
1489 if (i == currenttrack)
1490 status.insert(
"currentaudiotrack", list[i]);
1491 tracks.insert(
"SELECTAUDIO_" + QString::number(i), list[i]);
1494 status.insert(
"totalaudiotracks", tracks.size());
1495 if (!tracks.isEmpty())
1496 status.insert(
"audiotracks", tracks);
1520 for (
auto tit =
info.text.cbegin(); tit !=
info.text.cend(); ++tit)
1521 status.insert(tit.key(), tit.value());
1523 for (
auto vit =
info.values.cbegin(); vit !=
info.values.cend(); ++vit)
1524 status.insert(vit.key(), vit.value());
1551 LOG(VB_GENERAL, LOG_INFO, QString(
"Using Idle Timer. %1 minutes")
1573 else if (!Selection.empty())
1575 for (
const auto & ci : Selection)
1577 uint chanid = ci.m_chanId;
1578 QString channum = ci.m_chanNum;
1579 if (!chanid || channum.isEmpty())
1583 if (chanid && !channum.isEmpty() && !cards.isEmpty())
1621 if (!
info->GetChanID())
1628 QString key =
info->MakeUniqueKey();
1633 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"AskAllowRecording -- " +
1634 QString(
"adding '%1'").arg(
info->m_title));
1642 LOG(VB_GENERAL, LOG_INFO,
LOC +
"-- " +
1643 QString(
"removing '%1'").arg(
info->GetTitle()));
1647 delete (*it).m_info;
1664 QString single_rec = tr(
"MythTV wants to record \"%1\" on %2 in %d seconds. Do you want to:");
1666 QString record_watch = tr(
"Record and watch while it records");
1667 QString let_record1 = tr(
"Let it record and go back to the Main Menu");
1668 QString let_recordm = tr(
"Let them record and go back to the Main Menu");
1669 QString record_later1 = tr(
"Record it later, I want to watch TV");
1670 QString record_laterm = tr(
"Record them later, I want to watch TV");
1671 QString do_not_record1= tr(
"Don't let it record, I want to watch TV");
1672 QString do_not_recordm= tr(
"Don't let them record, I want to watch TV");
1679 if ((*it).m_expiry <= timeNow)
1682 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"-- " +
1683 QString(
"removing '%1'").arg((*it).m_info->m_title));
1685 delete (*it).m_info;
1693 std::chrono::milliseconds timeuntil = 0ms;
1700 (*it).m_isInSameInputGroup = (*it).m_isConflicting =
true;
1705 bool busy_input_grps_loaded =
false;
1706 std::vector<uint> busy_input_grps;
1713 (*it).m_isInSameInputGroup =
1714 (cardid == (*it).m_info->GetInputID());
1716 if ((*it).m_isInSameInputGroup)
1720 if (!busy_input_grps_loaded)
1723 busy_input_grps_loaded =
true;
1726 std::vector<uint> input_grps =
1729 for (
uint grp : input_grps)
1731#ifdef __cpp_lib_ranges_contains
1732 if (std::ranges::contains(busy_input_grps, grp))
1735 grp) != busy_input_grps.end())
1738 (*it).m_isInSameInputGroup =
true;
1748 if (!(*it).m_isInSameInputGroup)
1749 (*it).m_isConflicting =
false;
1750 else if (cardid == (*it).m_info->GetInputID())
1751 (*it).m_isConflicting =
true;
1753 (*it).m_isConflicting =
true;
1755 (busy_input.
m_mplexId == (*it).m_info->QueryMplexID())) ||
1757 (busy_input.
m_chanId == (*it).m_info->GetChanID())))
1758 (*it).m_isConflicting =
false;
1760 (*it).m_isConflicting =
true;
1762 conflict_count += (*it).m_isConflicting ? 1 : 0;
1769 if (conflict_count == 0)
1771 LOG(VB_GENERAL, LOG_INFO,
LOC +
"The scheduler wants to make "
1772 "a non-conflicting recording.");
1776 else if (conflict_count == 1 && ((*it).m_info->GetInputID() == cardid))
1779 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"UpdateOSDAskAllowDialog -- " +
1787 .replace(
"<num>", (*it).m_info->GetChanNum())
1788 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1789 .replace(
"<name>", (*it).m_info->GetChannelName());
1791 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1797 .m_timeout=timeuntil };
1798 dialog.m_buttons.push_back({ record_watch,
"DIALOG_ASKALLOW_WATCH_0",
false, !((*it).m_hasRec)} );
1799 dialog.m_buttons.push_back({ let_record1,
"DIALOG_ASKALLOW_EXIT_0" });
1800 dialog.m_buttons.push_back({ ((*it).m_hasLater) ? record_later1 : do_not_record1,
1801 "DIALOG_ASKALLOW_CANCELRECORDING_0",
false, ((*it).m_hasRec) });
1806 if (conflict_count > 1)
1809 "MythTV wants to record these programs in %d seconds:");
1813 bool has_rec =
false;
1816 if (!(*it).m_isConflicting)
1819 QString title = (*it).m_info->GetTitle();
1820 if ((title.length() < 10) && !(*it).m_info->GetSubtitle().isEmpty())
1821 title +=
": " + (*it).m_info->GetSubtitle();
1822 if (title.length() > 20)
1823 title = title.left(17) +
"...";
1827 .replace(
"<num>", (*it).m_info->GetChanNum())
1828 .replace(
"<sign>", (*it).m_info->GetChannelSchedulingID())
1829 .replace(
"<name>", (*it).m_info->GetChannelName());
1831 if (conflict_count > 1)
1833 message += tr(
"\"%1\" on %2").arg(title, channel);
1838 message = single_rec.arg((*it).m_info->GetTitle(), channel);
1839 has_rec = (*it).m_hasRec;
1843 if (conflict_count > 1)
1846 message += tr(
"Do you want to:");
1849 bool all_have_later =
true;
1850 timeuntil = 9999999ms;
1853 if ((*it).m_isConflicting)
1855 all_have_later &= (*it).m_hasLater;
1860 timeuntil = (9999999ms == timeuntil) ? 0ms : timeuntil;
1862 if (conflict_count > 1)
1868 .m_timeout=timeuntil,
1870 { let_recordm,
"DIALOG_ASKALLOW_EXIT_0",
false,
true },
1871 { all_have_later ? record_laterm : do_not_recordm,
"DIALOG_ASKALLOW_CANCELCONFLICTING_0" }
1880 .m_timeout=timeuntil,
1882 { let_record1,
"DIALOG_ASKALLOW_EXIT_0",
false, !has_rec},
1883 { all_have_later ? record_later1 : do_not_record1,
"DIALOG_ASKALLOW_CANCELRECORDING_0",
false, has_rec}
1896 LOG(VB_GENERAL, LOG_ERR,
"allowrecordingbox : askAllowLock is locked");
1900 if (
Action ==
"CANCELRECORDING")
1905 else if (
Action ==
"CANCELCONFLICTING")
1909 if (pgm.m_isConflicting)
1913 else if (
Action ==
"WATCH")
1979#define TRANSITION(ASTATE,BSTATE) ((ctxState == (ASTATE)) && (desiredNextState == (BSTATE)))
1981#define SET_NEXT() do { nextState = desiredNextState; changed = true; } while(false)
1982#define SET_LAST() do { nextState = ctxState; changed = true; } while(false)
1987 QByteArray msg_arr = msg.toLatin1();
1988 QString msg_i18n = TV::tr(msg_arr.constData());
1989 QByteArray msg_i18n_arr = msg_i18n.toLatin1();
1990 return (msg_arr == msg_i18n_arr) ? msg_i18n : msg;
2005 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Called after fatal error detected.");
2009 bool changed =
false;
2015 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning, called with no state to change to.");
2023 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Attempting to change from %1 to %2")
2028 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to set to an error state!");
2053 QString channum =
"";
2057 QStringList reclist;
2060 query.
prepare(
"SELECT channum FROM channel "
2061 "WHERE chanid = :CHANID");
2064 channum = query.
value(0).toString();
2066 channum = QString::number(chanid);
2069 QString::number(chanid));
2074 if (!reclist.empty())
2093 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- begin");
2095 if (chanid && !channum.isEmpty())
2100 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Spawning LiveTV Recorder -- end");
2104 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2118 LOG(VB_GENERAL, LOG_INFO,
LOC +
2119 QString(
"playbackURL(%1) inputtype(%2)")
2124 playbackURL,
false,
true,
2138 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
2193 LOG(VB_GENERAL, LOG_ERR,
LOC +
2194 "Couldn't find recorder for in-progress recording");
2213 QString message =
"COMMFLAG_REQUEST ";
2228 TV::tr(
"TV Player" ),
2255 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unknown state transition: %1 to %2")
2260 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Changing from %1 to %2")
2271 LOG(VB_GENERAL, LOG_INFO,
LOC +
"State is LiveTV");
2273 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateOSDInput done");
2275 LOG(VB_GENERAL, LOG_INFO,
LOC +
"UpdateLCD done");
2277 LOG(VB_GENERAL, LOG_INFO,
LOC +
"ITVRestart done");
2283 QString msg = tr(
"%1 Settings")
2336 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Main UI disabled.");
2339 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
" -- end");
2354 MaxWait = (MaxWait <= 0ms) ? 40s : MaxWait;
2357 bool recording =
false;
2361 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid Remote Encoder");
2369 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Lost contact with backend");
2373 std::this_thread::sleep_for(5us);
2379 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Timed out waiting for recorder to start");
2383 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Took %1 ms to start recorder.")
2384 .arg(
t.elapsed().count()));
2403 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- begin");
2417 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stopping ring buffer");
2428 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"stopping recorder");
2433 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"-- end");
2438 const int timer_id =
Event->timerId();
2446 bool handled =
true;
2507 if (!netCmd.isEmpty())
2533 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
"Last Program File does not exist");
2652 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Unknown timer: %1").arg(timer_id));
2662 QString lcd_time_string;
2663 bool showProgress =
true;
2680 lcd_time_string =
info.text[
"playedtime"] +
" / " +
info.text[
"totaltime"];
2682 if (lcd_time_string.length() > lcd->
getLCDWidth())
2683 lcd_time_string.remove(
' ');
2713 int timer = startTimer(Interval);
2715 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to start timer on line %1 of %2").arg(Line).arg(__FILE__));
2732 auto StateChange = [&]()
2750 QTimer::singleShot(0,
this, StateChange);
2755 auto InputChange = [&]()
2767 QTimer::singleShot(0,
this, InputChange);
2779 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Switching to program: %1")
2849 bool is_playing =
false;
2934 bool restartTimer =
false;
2940 restartTimer =
true;
2944 LOG(VB_CHANNEL, LOG_INFO,
"REC_PROGRAM -- channel change");
3010 if ((
Event->type() == QEvent::Resize))
3016 if ( (QEvent::KeyPress ==
Event->type() || QEvent::KeyRelease ==
Event->type())
3018 return TVPlaybackState::eventFilter(Object,
Event);
3020 QScopedPointer<QEvent> sNewEvent(
nullptr);
3024 if (QEvent::KeyPress ==
Event->type())
3039 switch (
Event->type())
3042 case QEvent::UpdateRequest:
3046 return TVPlaybackState::eventFilter(Object,
Event);
3049 return TVPlaybackState::eventFilter(Object,
Event);
3056 if (
Event ==
nullptr)
3057 return TVPlaybackState::event(
Event);
3059 if (QEvent::Resize ==
Event->type())
3064 const auto *qre =
dynamic_cast<const QResizeEvent*
>(
Event);
3067 return TVPlaybackState::event(
Event);
3076 if (QEvent::KeyPress ==
Event->type())
3078 const auto * ke =
dynamic_cast<QKeyEvent*
>(
Event);
3081 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"keypress: %1 '%2'")
3082 .arg(ke->key()).arg(ke->text()));
3090 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"mythgesture: g:%1 pos:%2,%3 b:%4")
3091 .arg(ge->GetGesture()).arg(ge->GetPosition().x())
3092 .arg(ge->GetPosition().y()).arg(ge->GetButton()));
3096 bool handled =
false;
3105 switch (
Event->type())
3108 case QEvent::UpdateRequest:
3118 return QObject::event(
Event);
3123 bool handled =
true;
3177 else if (
Action.startsWith(
"TOGGLE"))
3187 else if (
Action.startsWith(
"SELECT"))
3196 else if (
Action.startsWith(
"NEXT") ||
Action.startsWith(
"PREV"))
3198 int dir = (
Action.startsWith(
"NEXT")) ? +1 : -1;
3202 else if (
Action.endsWith(
"CC"))
3227 QStringList::const_iterator it;
3228 for (it = actions.begin(); it != actions.end(); ++it)
3230 if ((*it).startsWith(
"SYSEVENT") ||
3243 QList<QKeyEvent*> keyPressList;
3245 QStringList stringKeyList = KeyList.split(
',');
3246 for (
const auto & str : std::as_const(stringKeyList))
3248 QKeySequence keySequence(str);
3249 for (i = 0; i < keySequence.count(); i++)
3251#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3252 int keynum = keySequence[i];
3253 int keyCode = keynum & ~Qt::KeyboardModifierMask;
3254 auto modifiers =
static_cast<Qt::KeyboardModifiers
>(keynum & Qt::KeyboardModifierMask);
3256 int keyCode = keySequence[i].key();
3257 Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
3259 auto * keyEvent =
new QKeyEvent(QEvent::None, keyCode, modifiers);
3260 keyPressList.append(keyEvent);
3268 auto * keyEvent =
new QKeyEvent(QEvent::None, Qt::Key_Escape, Qt::NoModifier);
3269 keyPressList.append(keyEvent);
3272 return keyPressList;
3276 QStringList &Actions,
bool IsLiveTV)
3278 if (
Event && Context ==
"TV Playback")
3285 (
Event->GetButton() == Qt::LeftButton))
3289 QPoint pos =
Event->GetPosition();
3291 const int widthDivider = 4;
3292 int w4 = size.width() / widthDivider;
3293 region = pos.x() / w4;
3294 int h3 = size.height() / 3;
3295 region += (pos.y() / h3) * widthDivider;
3307 QStringList &Actions,
bool IsLiveTV,
bool AllowJumps)
3311 if (QEvent::KeyPress ==
Event->type())
3321 if (
Event ==
nullptr)
3327 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"ignoreKeys: %1").arg(ignoreKeys));
3338 auto* eKeyEvent =
dynamic_cast<QKeyEvent*
>(
Event);
3340 if (eKeyEvent->key() <= 0)
3343 switch(eKeyEvent->nativeScanCode())
3346 keycode = Qt::Key_MediaPause;
3354 auto *key =
new QKeyEvent(QEvent::KeyPress, keycode, eKeyEvent->modifiers());
3355 QCoreApplication::postEvent(
this, key);
3361 QStringList actions;
3362 bool handled =
false;
3363 bool alreadyTranslatedPlayback =
false;
3371 alreadyTranslatedPlayback =
true;
3373 if (handled || actions.isEmpty())
3376 bool esc =
IsActionable({
"ESCAPE",
"BACK" }, actions);
3387 if (QEvent::KeyPress ==
Event->type())
3389 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3447 if (QEvent::KeyPress ==
Event->type())
3449 auto *qke =
dynamic_cast<QKeyEvent*
>(
Event);
3452 const QString txt = qke->text();
3456 (void)txt.toInt(&ok, 16);
3457 if (ok || txt==
"_" || txt==
"-" || txt==
"#" || txt==
".")
3468 QStringList tt_actions;
3471 if (!handled && !tt_actions.isEmpty())
3473 for (
const QString&
action : std::as_const(tt_actions))
3485 if (!alreadyTranslatedPlayback)
3488 alreadyTranslatedPlayback =
true;
3491 if (!handled && !actions.isEmpty())
3493 for (
const QString&
action : std::as_const(actions))
3502 if (!alreadyTranslatedPlayback)
3505 if (handled || actions.isEmpty())
3513 if (QEvent::KeyPress ==
Event->type())
3529 for (
int i = 0; i < actions.size(); ++i)
3530 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"handled(%1) actions[%2](%3)")
3531 .arg(handled).arg(i).arg(actions[i]));
3539 for (
int i = 0; i < actions.size() && !handled; i++)
3541 const QString&
action = actions[i];
3543 int val =
action.toInt(&ok);
3561 bool handled =
true;
3581 for (
const auto&
action : std::as_const(Actions))
3592 static const QStringList passthrough =
3595 ACTION_MUTEAUDIO,
"CYCLEAUDIOCHAN",
"BOTTOMLINEMOVE",
"BOTTOMLINESAVE",
"TOGGLEASPECT"
3605 bool endmanualzoom =
false;
3606 bool handled =
true;
3607 bool updateOSD =
true;
3635 endmanualzoom =
true;
3637 endmanualzoom =
true;
3642 static const QStringList passthrough =
3650 QString msg = tr(
"Zoom Committed");
3654 msg = endmanualzoom ? tr(
"Zoom Ignored") :
3659 else if (endmanualzoom)
3706 bool handled =
true;
3731 bool handled =
true;
3754 bool handled =
true;
3777 bool handled =
true;
3812 bool IsDVD,
bool IsDVDStillFrame)
3814 bool handled =
true;
3816 if (
IsActionable(
"SKIPCOMMERCIAL", Actions) && !IsDVD) {
3818 }
else if (
IsActionable(
"SKIPCOMMBACK", Actions) && !IsDVD) {
3820 }
else if (
IsActionable(
"QUEUETRANSCODE", Actions) && !IsDVD) {
3822 }
else if (
IsActionable(
"QUEUETRANSCODE_AUTO", Actions) && !IsDVD) {
3824 }
else if (
IsActionable(
"QUEUETRANSCODE_HIGH", Actions) && !IsDVD) {
3826 }
else if (
IsActionable(
"QUEUETRANSCODE_MEDIUM", Actions) && !IsDVD) {
3828 }
else if (
IsActionable(
"QUEUETRANSCODE_LOW", Actions) && !IsDVD) {
3834 }
else if (
IsActionable(
"SPEEDINC", Actions) && !IsDVDStillFrame) {
3836 }
else if (
IsActionable(
"SPEEDDEC", Actions) && !IsDVDStillFrame) {
3840 }
else if (
IsActionable(
"CYCLECOMMSKIPMODE",Actions) && !IsDVD) {
3899 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
3925 std::chrono::milliseconds rate =
m_sigMonMode ? 0ms : 100ms;
3960 bool visible =
false;
4050 else if (
IsActionable({
"INFO",
"INFOWITHCUTLIST" }, Actions))
4071 for (
auto it = Actions.cbegin(); it != Actions.cend() && !handled; ++it)
4080 bool handled =
false;
4084 for (
int i = 0; i < Actions.size() && !handled; i++)
4086 const QString&
action = Actions[i];
4088 int val =
action.toInt(&ok);
4117 bool handled =
true;
4140 }
else if (
IsActionable(
"TOGGLEPICCONTROLS", Actions)) {
4189 info.text[
"title"] = tr(
"Position");
4197 bool handled =
true;
4219 else if (
IsActionable(
"NEXTSOURCE", Actions) && islivetv)
4223 else if (
IsActionable(
"PREVSOURCE", Actions) && islivetv)
4227 else if (
IsActionable(
"NEXTINPUT", Actions) && islivetv)
4235 else if (
IsActionable(
"PREVCHAN", Actions) && islivetv)
4308 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"(%1) ignoreKeys: %2").arg(
Command).arg(ignoreKeys));
4313 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Ignoring network control command because ignoreKeys is set");
4317 QStringList tokens =
Command.split(
" ", Qt::SkipEmptyParts);
4318 if (tokens.size() < 2)
4320 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Not enough tokens in network control command " + QString(
"'%1'").arg(
Command));
4332 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4333 "Ignoring network control command\n\t\t\t" +
4334 QString(
"because dialog is waiting for a response"));
4338 if (tokens[1] !=
"QUERY")
4341 if (tokens.size() == 3 && tokens[1] ==
"CHANID")
4347 else if (tokens.size() == 3 && tokens[1] ==
"CHANNEL")
4351 static const QRegularExpression kChannelNumRE { R
"(^[-\.\d_#]+$)" };
4352 if (tokens[2] ==
"UP")
4354 else if (tokens[2] ==
"DOWN")
4356 else if (tokens[2].contains(kChannelNumRE))
4360 else if (tokens.size() == 3 && tokens[1] ==
"SPEED")
4364 if (tokens[2] ==
"0x")
4371 else if (tokens[2] ==
"normal")
4381 static const QRegularExpression kSpeedRE { R
"(^\-*(\d*\.)?\d+x$)" };
4382 float tmpSpeed = 1.0F;
4385 if (tokens[2].contains(kSpeedRE))
4387 QString speed = tokens[2].left(tokens[2].length()-1);
4388 tmpSpeed = speed.toFloat(&ok);
4392 static const QRegularExpression re { R
"(^(\-*\d+)\/(\d+)x$)" };
4393 auto match = re.match(tokens[2]);
4394 if (match.hasMatch())
4396 QStringList matches = match.capturedTexts();
4397 int numerator = matches[1].toInt(&ok);
4398 int denominator = matches[2].toInt(&ok);
4400 if (ok && denominator != 0)
4401 tmpSpeed =
static_cast<float>(numerator) /
static_cast<float>(denominator);
4409 float searchSpeed = fabs(tmpSpeed);
4414 if (tmpSpeed == 0.0F)
4422 else if (tmpSpeed == 1.0F)
4441 else if (tmpSpeed > 1)
4449 else if (0.125F <= tmpSpeed && tmpSpeed <= 2.0F)
4457 LOG(VB_GENERAL, LOG_WARNING, QString(
"Couldn't find %1 speed. Setting Speed to 1x")
4458 .arg(
static_cast<double>(searchSpeed)));
4465 LOG(VB_GENERAL, LOG_ERR, QString(
"Found an unknown speed of %1").arg(tokens[2]));
4469 else if (tokens.size() == 2 && tokens[1] ==
"STOP")
4476 static const QRegularExpression kDigitsRE {
"^\\d+$" };
4480 if (tokens[2] ==
"BEGINNING")
4482 DoSeek(0, tr(
"Jump to Beginning"),
false,
true);
4484 else if (tokens[2] ==
"FORWARD")
4488 else if (tokens[2] ==
"BACKWARD")
4492 else if ((tokens[2] ==
"POSITION" ||
4493 tokens[2] ==
"POSITIONWITHCUTLIST") &&
4494 (tokens.size() == 4) &&
4495 (tokens[3].contains(kDigitsRE)))
4497 DoSeekAbsolute(tokens[3].toInt(), tokens[2] ==
"POSITIONWITHCUTLIST");
4500 else if (tokens.size() >= 3 && tokens[1] ==
"SUBTITLES")
4503 uint track = tokens[2].toUInt(&ok);
4515 uint size =
static_cast<uint>(subs.size());
4518 if (track >=
start && track < finish)
4527 finish =
start + size;
4528 if (track >=
start && track < finish)
4537 finish =
start + size;
4538 if (track >=
start && track < finish)
4547 finish =
start + size;
4548 if (track >=
start && track < finish)
4557 finish =
start + size;
4558 if (track >=
start && track < finish)
4567 finish =
start + size;
4568 if (track >=
start && track < finish)
4576 else if (tokens.size() >= 3 && tokens[1] ==
"VOLUME")
4578 static const QRegularExpression re {
"(\\d+)%?" };
4579 auto match = re.match(tokens[2]);
4580 if (match.hasMatch())
4582 QStringList matches = match.capturedTexts();
4584 LOG(VB_GENERAL, LOG_INFO, QString(
"Set Volume to %1%").arg(matches[1]));
4587 int vol = matches[1].toInt(&ok);
4591 if (0 <= vol && vol <= 100)
4595 else if (tokens.size() >= 3 && tokens[1] ==
"QUERY")
4597 if (tokens[2] ==
"POSITION")
4612 static const QRegularExpression re {
"Play (.*)x" };
4614 if (match.hasMatch())
4616 QStringList matches = match.capturedTexts();
4617 speedStr = QString(
"%1x").arg(matches[1]);
4629 QString infoStr =
"";
4653 infoStr =
"Recorded";
4661 QString bufferFilename =
4663 if ((infoStr ==
"Recorded") || (infoStr ==
"LiveTV"))
4665 infoStr += QString(
" %1 %2 %3 %4 %5 %6 %7")
4666 .arg(
info.text[
"description"],
4671 QString::number(fplay),
4673 QString::number(rate));
4677 QString position =
info.text[
"description"].section(
" ",0,0);
4678 infoStr += QString(
" %1 %2 %3 %4 %5")
4682 QString::number(fplay),
4683 QString::number(rate));
4686 infoStr += QString(
" Subtitles:");
4691 infoStr += QString(
" *0:[None]*");
4693 infoStr += QString(
" 0:[None]");
4698 for (
int i = 0; i < subs.size(); i++)
4701 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4703 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4708 for (
int i = 0; i < subs.size(); i++)
4711 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4713 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4718 for (
int i = 0; i < subs.size(); i++)
4721 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4723 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4728 for (
int i = 0; i < subs.size(); i++)
4731 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4733 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4738 for (
int i = 0; i < subs.size(); i++)
4741 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4743 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4748 for (
int i = 0; i < subs.size(); i++)
4751 infoStr += QString(
" *%1:[%2]*").arg(n).arg(subs[i]);
4753 infoStr += QString(
" %1:[%2]").arg(n).arg(subs[i]);
4759 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4763 else if (tokens[2] ==
"VOLUME")
4766 QString message = QString(
"NETWORK_CONTROL ANSWER %1").arg(infoStr);
4775 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- begin").arg(
StateToString(desiredState)));
4782 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Created player."));
4787 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"Failed to create player."));
4790 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"(%1) -- end %2")
4896 bool paused =
false;
4918 bool ignore =
false;
4919 bool paused =
false;
4944 if (Time > -0.001F && Time < +0.001F)
4947 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1 seconds").arg(
static_cast<double>(Time)));
4968 else if (Time < 0.0F)
4980 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"%1").arg(FrameNum));
5006 const int kRewind = 4;
5007 const int kForward = 8;
5008 const int kSticky = 16;
5009 const int kSlippery = 32;
5010 const int kRelative = 64;
5011 const int kAbsolute = 128;
5012 const int kIgnoreCutlist = 256;
5013 const int kWhenceMask = 3;
5018 flags =
ARBSEEK_END | kForward | kSticky | kAbsolute;
5024 flags =
ARBSEEK_SET | kRewind | kSticky | kAbsolute;
5030 int direction = (flags & kRewind) ? -1 : 1;
5039 QString message = (flags & kRewind) ? tr(
"Rewind") :
5041 if (flags & kAbsolute)
5043 float time = direction;
5044 DoSeek(time, message,
true, (flags & kIgnoreCutlist) == 0);
5051 uint64_t targetRel = frameRel +
static_cast<uint64_t
>(direction);
5052 if (frameRel == 0 && direction < 0)
5056 targetRel = std::min(targetRel, maxRel);
5064 else if (flags & kSticky)
5068 else if (flags & kRewind)
5088void TV::DoSeek(
float Time,
const QString &Msg,
bool TimeIsOffset,
bool HonorCutlist)
5093 bool limitkeys =
false;
5135 DoSeek(Seconds, tr(
"Jump To"),
false, HonorCutlist);
5147 int64_t time = ((seek / 100) * 3600) + ((seek % 100) * 60);
5151 DoSeek(time, tr(
"Jump Ahead"),
true, HonorCutlist);
5155 DoSeek(-time, tr(
"Jump Back"),
true, HonorCutlist);
5168 DoSeek(std::max(0.0F, dur -
static_cast<float>(time)), tr(
"Jump To"),
false, HonorCutlist);
5301 auto index =
static_cast<size_t>(Index);
5370 QString jobHost =
"";
5375 QString msg = tr(
"Try Again");
5382 msg = tr(
"Transcoding");
5392 int num_chapters = 0;
5397 return num_chapters;
5445 int currentTitle = 0;
5450 return currentTitle;
5465 int currentAngle = 0;
5470 return currentAngle;
5485 std::chrono::seconds seconds = 0s;
5548 info.text[
"title"] = tr(
"Skip");
5549 info.text[
"description"] = tr(
"Searching");
5561 QMap<uint,InputInfo> sources;
5566 uint sourceid =
info[
"sourceid"].toUInt();
5569 for (
auto & input : inputs)
5572 if ((!sources.contains(input.m_sourceId)) ||
5573 ((cardid == input.m_inputId) && (cardid != sources[input.m_sourceId].m_inputId)))
5575 sources[input.m_sourceId] = input;
5580 QMap<uint,InputInfo>::const_iterator beg = sources.constFind(sourceid);
5581 QMap<uint,InputInfo>::const_iterator sit = beg;
5583 if (sit == sources.constEnd())
5589 if (sit == sources.constEnd())
5590 sit = sources.constBegin();
5595 if (sit != sources.constBegin())
5601 QMap<uint,InputInfo>::const_iterator tmp = sources.constBegin();
5602 while (tmp != sources.constEnd())
5629 QCoreApplication::processEvents();
5631 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1,'%2',%3)").arg(ChanID).arg(ChanNum).arg(InputID));
5638 QStringList reclist;
5641 reclist.push_back(QString::number(InputID));
5643 else if (ChanID || !ChanNum.isEmpty())
5650 if (!reclist.empty())
5658 if (ChanID && ChanNum.isEmpty())
5661 if (!ChanNum.isEmpty())
5704 if (ChanNum.isEmpty() && ChanID)
5706 if (ChanNum.isEmpty() && InputID)
5712 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully restarted");
5725 playbackURL,
false,
true,
5752 LOG(VB_GENERAL, LOG_ERR,
LOC +
"LiveTV not successfully started");
5766 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No recorder to switch to...");
5780 LOG(VB_GENERAL, LOG_ERR,
"TV::ToggleChannelFavorite() -- currently disabled");
5848 bool commitSmart =
false;
5860 inputStr = inputStr.isEmpty() ?
"?" : inputStr;
5864 inputStr = entryStr +
" " + inputStr;
5868 inputStr = tr(
"Seek:",
"seek to location") +
" " + inputStr;
5878static QString
add_spacer(
const QString &chan,
const QString &spacer)
5880 if ((chan.length() >= 2) && !spacer.isEmpty())
5881 return chan.left(chan.length()-1) + spacer + chan.right(1);
5893#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
5894 int size = chan.size();
5896 qsizetype size = chan.size();
5898 if ((size > 2) && (chan.at(size - 1) == chan.at(size - 2)))
5901 chan.right(1).toUInt(&ok);
5904 chan = chan.left(chan.length()-1);
5912 QString needed_spacer;
5913 uint pref_cardid = 0;
5914 bool is_not_complete =
true;
5916 bool valid_prefix =
false;
5920 chan, pref_cardid, is_not_complete, needed_spacer);
5923#if DEBUG_CHANNEL_PREFIX
5924 LOG(VB_GENERAL, LOG_DEBUG, QString(
"valid_pref(%1) cardid(%2) chan(%3) "
5925 "pref_cardid(%4) complete(%5) sp(%6)")
5926 .arg(valid_prefix).arg(0).arg(chan)
5927 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5935 else if (!needed_spacer.isEmpty())
5941#if DEBUG_CHANNEL_PREFIX
5942 LOG(VB_GENERAL, LOG_DEBUG, QString(
" ValidPref(%1) CardId(%2) Chan(%3) "
5943 " PrefCardId(%4) Complete(%5) Sp(%6)")
5945 .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
5952 return !is_not_complete;
5957 bool commited =
false;
5959 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
5960 QString(
"livetv(%1) qchannum(%2) qchanid(%3)")
5990 if (channum.isEmpty())
6013 uint old_chanid = 0;
6019 LOG(VB_GENERAL, LOG_ERR,
LOC +
6020 "no active ctx playingInfo.");
6082 uint cardid,
const QString &channum)
6085 uint cur_sourceid = 0;
6098 if (cur_sourceid != sourceid && sourceid)
6105 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"(%1, '%2')").arg(Chanid).arg(
Channum));
6111 QStringList reclist;
6112 QVector<uint> tunable_on;
6116 if (channum.isEmpty() && Chanid)
6137 QString needed_spacer;
6138 uint pref_cardid = 0;
6143 dummy, needed_spacer);
6145 LOG(VB_CHANNEL, LOG_INFO,
LOC +
6146 QString(
"CheckChannelPrefix(%1, pref_cardid %2, %3, '%4') "
6148 .arg(
Channum).arg(pref_cardid).arg(dummy).arg(needed_spacer)
6152 if (pref_cardid != cardid)
6161 getit = !tunable_on.contains(cardid);
6169 if (tunable_on.empty())
6175 for (
const auto& rec : std::as_const(tmp))
6177 if ((Chanid == 0U) || tunable_on.contains(rec.toUInt()))
6178 reclist.push_back(rec);
6183 if (!reclist.empty())
6247 for (
const auto & option : Options)
6249 uint chanid = option.m_chanId;
6250 QString channum = option.m_chanNum;
6269 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Previous channel number '%1'").arg(channum));
6270 if (channum.isEmpty())
6280 if (!ImmediateChange)
6286 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"'%1'->'%2'")
6287 .arg(cur_channum, prev_channum));
6290 if (cur_channum != prev_channum && !prev_channum.isEmpty())
6299 if (ImmediateChange)
6313 emit
HideAll(
true,
nullptr,
true);
6331 bool hideAll =
false;
6347 else if (is_prog_info_disp && !paused)
6351 else if (IncludeStatusOSD)
6369 info.text[
"title"] = (paused ? tr(
"Paused") : tr(
"Position"));
6415 const QString& Value,
int Type,
const QString& Units,
6419 info.values.insert(
"position", Position);
6420 info.values.insert(
"relposition", Position);
6421 info.text.insert(
"title", Title);
6422 info.text.insert(
"description", Desc);
6423 info.text.insert(
"value", Value);
6424 info.text.insert(
"units", Units);
6430 LOG(VB_PLAYBACK, LOG_INFO, QString(
"UpdateOSDSeekMessage(%1, %2)").arg(Msg).arg(Timeout));
6436 info.text[
"title"] = Msg;
6471 infoMap[
"callsign"].isEmpty())
6483 SignalMonitorList::const_iterator it;
6484 for (it = slist.begin(); it != slist.end(); ++it)
6485 if (
"error" == it->GetShortName())
6486 infoMap[QString(
"error%1").arg(i++)] = it->GetName();
6488 for (it = slist.begin(); it != slist.end(); ++it)
6489 if (
"message" == it->GetShortName())
6490 infoMap[QString(
"message%1").arg(i++)] = it->GetName();
6494 uint ber = 0xffffffff;
6506 for (it = slist.begin(); it != slist.end(); ++it)
6508 if (
"error" == it->GetShortName())
6510 err = it->GetName();
6514 if (
"message" == it->GetShortName())
6516 msg = it->GetName();
6517 LOG(VB_GENERAL, LOG_INFO,
"msg: " + msg);
6521 infoMap[it->GetShortName()] = QString::number(it->GetValue());
6522 if (
"signal" == it->GetShortName())
6523 sig = it->GetNormalizedValue(0, 100);
6524 else if (
"snr" == it->GetShortName())
6525 snr = it->GetValue();
6526 else if (
"ber" == it->GetShortName())
6527 ber =
static_cast<uint>(it->GetValue());
6528 else if (
"pos" == it->GetShortName())
6529 pos = it->GetValue();
6530 else if (
"script" == it->GetShortName())
6531 tuned = it->GetValue();
6532 else if (
"seen_pat" == it->GetShortName())
6533 pat = it->IsGood() ?
"a" :
"_";
6534 else if (
"matching_pat" == it->GetShortName())
6535 pat = it->IsGood() ?
"A" : pat;
6536 else if (
"seen_pmt" == it->GetShortName())
6537 pmt = it->IsGood() ?
"m" :
"_";
6538 else if (
"matching_pmt" == it->GetShortName())
6539 pmt = it->IsGood() ?
"M" : pmt;
6540 else if (
"seen_mgt" == it->GetShortName())
6541 mgt = it->IsGood() ?
"g" :
"_";
6542 else if (
"matching_mgt" == it->GetShortName())
6543 mgt = it->IsGood() ?
"G" : mgt;
6544 else if (
"seen_vct" == it->GetShortName())
6545 vct = it->IsGood() ?
"v" :
"_";
6546 else if (
"matching_vct" == it->GetShortName())
6547 vct = it->IsGood() ?
"V" : vct;
6548 else if (
"seen_nit" == it->GetShortName())
6549 nit = it->IsGood() ?
"n" :
"_";
6550 else if (
"matching_nit" == it->GetShortName())
6551 nit = it->IsGood() ?
"N" : nit;
6552 else if (
"seen_sdt" == it->GetShortName())
6553 sdt = it->IsGood() ?
"s" :
"_";
6554 else if (
"matching_sdt" == it->GetShortName())
6555 sdt = it->IsGood() ?
"S" : sdt;
6556 else if (
"seen_crypt" == it->GetShortName())
6557 crypt = it->IsGood() ?
"c" :
"_";
6558 else if (
"matching_crypt" == it->GetShortName())
6559 crypt = it->IsGood() ?
"C" : crypt;
6562 infoMap[
"signal"] = QString::number(sig);
6566 QString slock = (
"1" == infoMap[
"slock"]) ?
"L" :
"l";
6567 QString lockMsg = (slock==
"L") ? tr(
"Partial Lock") : tr(
"No Lock");
6568 QString sigMsg = allGood ? tr(
"Lock") : lockMsg;
6570 QString sigDesc = tr(
"Signal %1%").arg(sig,2);
6572 sigDesc +=
" | " + tr(
"S/N %1dB").arg(log10(snr), 3,
'f', 1);
6573 if (ber != 0xffffffff)
6574 sigDesc +=
" | " + tr(
"BE %1",
"Bit Errors").arg(ber, 2);
6575 if ((pos >= 0) && (pos < 100))
6576 sigDesc +=
" | " + tr(
"Rotor %1%").arg(pos,2);
6580 else if (tuned == 2)
6582 else if (tuned == 3)
6587 sigDesc = sigDesc + QString(
" | (%1%2%3%4%5%6%7%8%9) %10")
6588 .arg(tuneCode, slock, pat, pmt, mgt, vct,
6594 else if (!msg.isEmpty())
6597 infoMap[
"description"] = sigDesc;
6604 if (allGood || (pmt ==
"M"))
6613 bool timed_out =
false;
6628 LOG(VB_GENERAL, LOG_ERR,
LOC +
6629 "You have no OSD, but tuning has already taken too long.");
6655 static QString s_nextSrc =
GET_KEY(
"TV Playback",
"NEXTSOURCE");
6656 static QString s_togCards =
GET_KEY(
"TV Playback",
"NEXTINPUT");
6658 QString message = tr(
6659 "You should have received a channel lock by now. "
6660 "You can continue to wait for a signal, or you "
6661 "can change the channel with %1 or %2, change "
6662 "video source (%3), inputs (%4), etc.")
6663 .arg(s_chanUp, s_chanDown, s_nextSrc, s_togCards);
6669 .m_buttons={ {tr(
"OK"),
"DIALOG_INFO_CHANNELLOCK_0" } },
6670 .m_back={ .m_text=
"", .m_data=
"DIALOG_INFO_CHANNELLOCK_0", .m_exit=
true } });
6675 bool result =
false;
6741 dvdName = tr(
"DVD");
6745 mainStatus = tr(
"Menu");
6749 mainStatus = tr(
"Still Frame");
6753 int playingTitle = 0;
6754 int playingPart = 0;
6759 mainStatus = tr(
"Title: %1 (%2)").arg(playingTitle)
6761 subStatus = tr(
"Chapter: %1/%2").arg(playingPart).arg(totalParts);
6796 for (
uint i : std::as_const(list))
6797 ret += QString(
"%1,").arg(i);
6800 return ret.left(ret.length()-1);
6807 QVector<uint> tunable_cards;
6811 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6812 return tunable_cards;
6816 mplexid = (32767 == mplexid) ? 0 : mplexid;
6818 uint excluded_input = 0;
6826 for (
auto & input : inputs)
6828 if (input.m_sourceId != sourceid)
6831 if (input.m_mplexId &&
6832 input.m_mplexId != mplexid)
6835 if (!input.m_mplexId && input.m_chanId &&
6836 input.m_chanId != ChanId)
6839 tunable_cards.push_back(input.m_inputId);
6842 if (tunable_cards.empty())
6843 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) - no").arg(ChanId));
6845 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"ChanId (%1) yes { %2 }").arg(ChanId).arg(
toCommaList(tunable_cards)));
6846 return tunable_cards;
6849void TV::Embed(
bool Embed, QRect Rect,
const QStringList& Data)
6874 if (!Data.isEmpty())
6886 if (Pause ^ waspaused)
6888 if (Pause ^ waspaused)
6913 LOG(VB_GENERAL, LOG_ERR,
LOC +
"no active ctx playingInfo.");
6940 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"Pausing player: %1").arg(pause));
7023 QString message = QString(
"START_EPG %1 %2").arg(EditType).arg(arg);
7025 QCoreApplication::postEvent(
this, me);
7042 QString appName = tr(
"Video");
7048 appName = tr(
"DVD");
7050 lcd->switchToVolume(appName);
7076 const float kTimeStretchMin = 0.125;
7077 const float kTimeStretchMax = 2.0;
7078 const float kTimeStretchStep = 0.05F;
7082 if (new_ts_normal > kTimeStretchMax &&
7085 new_ts_normal = kTimeStretchMax;
7087 else if (new_ts_normal < kTimeStretchMin &&
7090 new_ts_normal = kTimeStretchMin;
7093 if (new_ts_normal > kTimeStretchMax ||
7094 new_ts_normal < kTimeStretchMin)
7157 QString message = tr(
"MythTV was set to sleep after %1 minutes and will exit in %d seconds.\n"
7158 "Do you wish to continue watching?")
7165 .m_buttons={ { tr(
"Yes"),
"DIALOG_SLEEP_YES_0" },
7166 { tr(
"No"),
"DIALOG_SLEEP_NO_0" } }});
7187 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching TV, exiting");
7197 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Sleep timeout reached, exiting player.");
7215 QString message = tr(
"MythTV has been idle for %1 minutes and "
7216 "will exit in %d seconds. Are you still watching?")
7223 .m_buttons={ { tr(
"Yes"),
"DIALOG_IDLE_YES_0" },
7224 { tr(
"No"),
"DIALOG_IDLE_NO_0" }}});
7247 LOG(VB_GENERAL, LOG_INFO,
LOC +
"No longer watching LiveTV, exiting");
7260 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Idle timeout reached, leaving LiveTV");
7300 QString message = me->
Message();
7302 if (message.isEmpty())
7305 std::chrono::milliseconds
timeout = 0ms;
7306 if (me->ExtraDataCount() == 1)
7308 auto t = std::chrono::seconds(me->ExtraData(0).toInt());
7309 if (
t > 0s &&
t < 1000s)
7333 if (dce->GetData().userType() == qMetaTypeId<MythTVMenuNodeTuple>())
7337 QDomNode Node = Menu.GetNodeFromPath(data.m_path);
7338 if (dce->GetResult() == -1)
7345 OSDDialogEvent(dce->GetResult(), dce->GetResultText(), dce->GetData().toString());
7370 LOG(VB_GENERAL, LOG_NOTICE,
"DVD has been ejected, exiting playback");
7385 QString message = me->
Message();
7388 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
7390 if (me->ExtraDataCount() == 1)
7393 int value = me->ExtraData(0).toInt();
7423 if (me->ExtraDataCount() >= 2)
7425 width = me->ExtraData(0).toInt();
7426 height = me->ExtraData(1).toInt();
7428 if (me->ExtraDataCount() == 3)
7437 else if (message.startsWith(
"DONE_RECORDING"))
7439 std::chrono::seconds seconds = 0s;
7442 if (tokens.size() == NUMTOKENS)
7444 cardnum = tokens[1].toUInt();
7445 seconds = std::chrono::seconds(tokens[2].toInt());
7450 LOG(VB_GENERAL, LOG_ERR, QString(
"DONE_RECORDING event received "
7451 "with invalid number of arguments, "
7452 "%1 expected, %2 actual")
7454 .arg(tokens.size()-1));
7494 if (message.startsWith(
"ASK_RECORDING "))
7497 bool hasrec =
false;
7498 bool haslater =
false;
7499 if (tokens.size() >= 5)
7501 cardnum = tokens[1].toUInt();
7502 timeuntil = tokens[2].toInt();
7503 hasrec = (tokens[3].toInt() != 0);
7504 haslater = (tokens[4].toInt() != 0);
7506 LOG(VB_GENERAL, LOG_DEBUG,
7507 LOC + message + QString(
" hasrec: %1 haslater: %2")
7508 .arg(hasrec).arg(haslater));
7517 if (message.startsWith(
"QUIT_LIVETV"))
7519 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7532 if (message.startsWith(
"LIVETV_WATCH"))
7535 if (tokens.size() >= 3)
7537 cardnum = tokens[1].toUInt();
7538 watch = tokens[2].toInt();
7562 if (message.startsWith(
"LIVETV_CHAIN"))
7565 if ((tokens.size() >= 2) && tokens[1] ==
"UPDATE")
7574 if (message.startsWith(
"EXIT_TO_MENU"))
7583 if (message.startsWith(
"SIGNAL"))
7585 cardnum = (tokens.size() >= 2) ? tokens[1].toUInt() : 0;
7586 const QStringList& signalList = me->ExtraDataList();
7602 if (message.startsWith(
"NETWORK_CONTROL"))
7604 if ((tokens.size() >= 2) &&
7605 (tokens[1] !=
"ANSWER") && (tokens[1] !=
"RESPONSE"))
7607 QStringList tokens2 = message.split(
" ", Qt::SkipEmptyParts);
7608 if ((tokens2.size() >= 2) &&
7609 (tokens2[1] !=
"ANSWER") && (tokens2[1] !=
"RESPONSE"))
7618 if (message.startsWith(
"START_EPG"))
7620 int editType = tokens[1].toInt();
7621 QString arg = message.section(
" ", 2, -1);
7625 if (message.startsWith(
"COMMFLAG_START") && (tokens.size() >= 2))
7628 QDateTime evrecstartts;
7640 QString msg =
"COMMFLAG_REQUEST ";
7647 if (message.startsWith(
"COMMFLAG_UPDATE") && (tokens.size() >= 3))
7650 QDateTime evrecstartts;
7664 QStringList marks = tokens[2].split(
",", Qt::SkipEmptyParts);
7665 for (
int j = 0; j < marks.size(); j++)
7667 mark = marks[j].split(
":", Qt::SkipEmptyParts);
7668 if (marks.size() >= 2)
7669 newMap[mark[0].toULongLong()] =
static_cast<MarkTypes>(mark[1].toInt());
7679 if (message ==
"NOTIFICATION")
7700 recinfo.
ToMap(infoMap);
7717 map.insert(
"message_text", tr(
"Record"));
7725 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"Unknown recording during live tv.");
7738 cmdmsg = tr(
"Record");
7741 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record on");
7750 cmdmsg = tr(
"Cancel Record");
7753 LOG(VB_RECORD, LOG_INFO,
LOC +
"Toggling Record off");
7801 sup &= ~kPictureAttributeSupported_Range;
7835 title = tr(
"Adjust Volume");
7852 if (Type ==
"EDIT_CUT_POINTS")
7858 "menu_cutlist.xml", tr(
"Edit Cut Points"),
7859 metaObject()->className(),
"TV Editing");
7865 else if (Type ==
"EDIT_CUT_POINTS_COMPACT")
7871 "menu_cutlist_compact.xml", tr(
"Edit Cut Points"),
7872 metaObject()->className(),
"TV Editing");
7878 else if (Type ==
"EXIT_EDIT_MODE")
7881 .m_message=tr(
"Exit Recording Editor") };
7882 dialog.m_buttons.push_back( { tr(
"Save Cuts and Exit"),
"DIALOG_CUTPOINT_SAVEEXIT_0" } );
7883 dialog.m_buttons.push_back( { tr(
"Exit Without Saving"),
"DIALOG_CUTPOINT_REVERTEXIT_0" } );
7884 dialog.m_buttons.push_back( { tr(
"Save Cuts"),
"DIALOG_CUTPOINT_SAVEMAP_0" } );
7885 dialog.m_buttons.push_back( { tr(
"Undo Changes"),
"DIALOG_CUTPOINT_REVERT_0" } );
7886 dialog.m_back = { .m_text=
"",
7887 .m_data=
"DIALOG_CUTPOINT_DONOTHING_0",
7892 map.insert(
"title", tr(
"Edit"));
7904 if (
Action ==
"DONOTHING" && osd)
7909 QStringList actions(
Action);
7911 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unrecognised cutpoint action");
7941 QString message = tr(
"This program is currently being edited");
7942 QString def = QString(
"DIALOG_EDITING_CONTINUE_%1").arg(
static_cast<int>(paused));
7947 .m_buttons={ { tr(
"Continue Editing"), def,
false,
true },
7948 { tr(
"Do not edit"), QString(
"DIALOG_EDITING_STOP_%1").arg(
static_cast<int>(paused)) }},
7949 .m_back={ .m_text=
"", .m_data=def, .m_exit=
true} });
7965 if (!WasPaused && paused)
7982 for (
auto it = newMap.cbegin(); it != newMap.cend(); ++it)
7983 infoMap.insert(it.key(), *it);
8042 if (osd &&
Action ==
"PROBE")
8050 else if (osd &&
Action ==
"OK")
8058 else if (osd &&
Action ==
"QUIT")
8072 const QString keys[4] = {
"XMLTV",
"callsign",
"channame",
"channum", };
8081 QMap<QString,bool> modifiable;
8082 modifiable[
"callsign"] = Info[
"callsign"].isEmpty();
8083 if (!modifiable[
"callsign"])
8085 QString unsetsign = tr(
"UNKNOWN%1",
"Synthesized callsign");
8086 int unsetcmpl = unsetsign.length() - 2;
8087 unsetsign = unsetsign.left(unsetcmpl);
8088 if (Info[
"callsign"].left(unsetcmpl) == unsetsign)
8089 modifiable[
"callsign"] =
true;
8091 modifiable[
"channame"] = Info[
"channame"].isEmpty();
8093 const std::array<const QString,2> xds_keys {
"callsign",
"channame", };
8094 for (
const auto & key : xds_keys)
8096 if (!modifiable[key])
8106 if ((key ==
"callsign") &&
8107 ((tmp.length() > 5) || (tmp.indexOf(
" ") >= 0)))
8119 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"result %1 text %2 action %3")
8120 .arg(QString::number(Result), Text,
Action));
8126 bool handled =
true;
8127 if (
Action.startsWith(
"DIALOG_"))
8129 Action.remove(
"DIALOG_");
8130 QStringList desc =
Action.split(
"_");
8131 bool valid = desc.size() == 3;
8137 else if (valid && desc[0] ==
"VIDEOEXIT")
8141 else if (valid && desc[0] ==
"SLEEP")
8145 else if (valid && desc[0] ==
"IDLE")
8149 else if (valid && desc[0] ==
"INFO")
8153 else if (valid && desc[0] ==
"EDITING")
8157 else if (valid && desc[0] ==
"ASKALLOW")
8161 else if (valid && desc[0] ==
"EDITOR")
8165 else if (valid && desc[0] ==
"CUTPOINT")
8169 else if ((valid && desc[0] ==
"DELETE") ||
8170 (valid && desc[0] ==
"CONFIRM"))
8179 LOG(VB_GENERAL, LOG_ERR,
"Unrecognised dialog event.");
8182 else if (Result < 0)
8199 else if (
Action ==
"CANCELPLAYLIST")
8225 else if (
Action ==
"TOGGLEMANUALZOOM")
8237 else if (
Action ==
"TOGGLESTRETCH")
8249 else if (
Action.startsWith(
"ADJUSTSTRETCH"))
8251 bool floatRead =
false;
8252 float stretch =
Action.right(
Action.length() - 13).toFloat(&floatRead);
8267 else if (
Action.startsWith(
"SELECTSCAN_"))
8299 else if (
Action.startsWith(
"TOGGLEPICCONTROLS"))
8304 else if (
Action ==
"TOGGLEASPECT")
8308 else if (
Action.startsWith(
"TOGGLEASPECT"))
8312 else if (
Action ==
"TOGGLEFILL")
8316 else if (
Action.startsWith(
"TOGGLEFILL"))
8320 else if (
Action ==
"MENU")
8324 else if (
Action ==
"AUTODETECT_FILL")
8334 if (
Action ==
"CHANGROUP_ALL_CHANNELS")
8340 Action.remove(
"CHANGROUP_");
8346 QString cur_channum;
8347 QString new_channum;
8353 new_channum = cur_channum;
8355 auto it = list.cbegin();
8356 for (; it != list.cend(); ++it)
8358 if ((*it).m_chanNum == cur_channum)
8364 if (it == list.end())
8369 if (it != list.end())
8370 new_channum = (*it).m_chanNum;
8373 LOG(VB_CHANNEL, LOG_INFO,
LOC +
8374 QString(
"Channel Group: '%1'->'%2'")
8375 .arg(cur_channum, new_channum));
8381 if (cur_channum != new_channum && !new_channum.isEmpty())
8400 else if (
Action ==
"SCHEDULE")
8413 else if (
Action.startsWith(
"JUMPCAST|"))
8415 QStringList tokens =
Action.split(
"|");
8416 if (tokens.size() == 3)
8418 else if (tokens.size() == 4)
8423 else if (
Action.startsWith(
"VISUALISER"))
8427 else if (
Action.startsWith(
"3D"))
8436 if (
Action ==
"TOGGLEBROWSE")
8440 else if (
Action ==
"PREVCHAN")
8444 else if (
Action.startsWith(
"SWITCHTOINPUT_"))
8449 else if (
Action ==
"EDIT")
8480 int chapter =
Action.right(3).toInt();
8485 int title =
Action.right(3).toInt();
8490 int angle =
Action.right(3).toInt();
8493 else if (
Action ==
"EDIT")
8498 else if (
Action ==
"TOGGLEAUTOEXPIRE")
8502 else if (
Action.startsWith(
"TOGGLECOMMSKIP"))
8506 else if (
Action ==
"QUEUETRANSCODE")
8510 else if (
Action ==
"QUEUETRANSCODE_AUTO")
8514 else if (
Action ==
"QUEUETRANSCODE_HIGH")
8518 else if (
Action ==
"QUEUETRANSCODE_MEDIUM")
8522 else if (
Action ==
"QUEUETRANSCODE_LOW")
8544 LOG(VB_GENERAL, LOG_ERR,
LOC +
8545 "Unknown menu action selected: " +
Action);
8556 bool visible =
false;
8569 if (
Action ==
"CHANNELLOCK")
8574#define BUTTON(action, text) \
8575 result = Context.AddButton(Menu, active, (action), (text), "", false, "")
8576#define BUTTON2(action, textActive, textInactive) \
8577 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), false, "")
8578#define BUTTON3(action, textActive, textInactive, isMenu) \
8579 result = Context.AddButton(Menu, active, (action), (textActive), (textInactive), (isMenu), "")
8594 const QString &actionName = Context.
m_action;
8596 bool result =
false;
8599 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8616 if (actionName ==
"DIALOG_CUTPOINT_MOVEPREV_0")
8624 BUTTON2(actionName, tr(
"Move Previous Cut End Here"), tr(
"Move Start of Cut Here"));
8627 else if (actionName ==
"DIALOG_CUTPOINT_MOVENEXT_0")
8635 BUTTON2(actionName, tr(
"Move Next Cut Start Here"), tr(
"Move End of Cut Here"));
8638 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOBEGINNING_0")
8641 BUTTON(actionName, tr(
"Cut to Beginning"));
8643 else if (actionName ==
"DIALOG_CUTPOINT_CUTTOEND_0")
8648 BUTTON(actionName, tr(
"Cut to End"));
8651 else if (actionName ==
"DIALOG_CUTPOINT_DELETE_0")
8654 BUTTON2(actionName, tr(
"Delete This Cut"), tr(
"Join Surrounding Cuts"));
8656 else if (actionName ==
"DIALOG_CUTPOINT_NEWCUT_0")
8659 BUTTON(actionName, tr(
"Add New Cut"));
8661 else if (actionName ==
"DIALOG_CUTPOINT_UNDO_0")
8665 QString text = tr(
"Undo - %1");
8666 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8669 else if (actionName ==
"DIALOG_CUTPOINT_REDO_0")
8673 QString text = tr(
"Redo - %1");
8674 result = Context.
AddButton(Menu, active, actionName, text,
"",
false,
8677 else if (actionName ==
"DIALOG_CUTPOINT_CLEARMAP_0")
8679 BUTTON(actionName, tr(
"Clear Cuts"));
8681 else if (actionName ==
"DIALOG_CUTPOINT_INVERTMAP_0")
8683 BUTTON(actionName, tr(
"Reverse Cuts"));
8685 else if (actionName ==
"DIALOG_CUTPOINT_LOADCOMMSKIP_0")
8687 BUTTON(actionName, tr(
"Load Detected Commercials"));
8689 else if (actionName ==
"DIALOG_CUTPOINT_REVERT_0")
8691 BUTTON(actionName, tr(
"Undo Changes"));
8693 else if (actionName ==
"DIALOG_CUTPOINT_REVERTEXIT_0")
8695 BUTTON(actionName, tr(
"Exit Without Saving"));
8697 else if (actionName ==
"DIALOG_CUTPOINT_SAVEMAP_0")
8699 BUTTON(actionName, tr(
"Save Cuts"));
8701 else if (actionName ==
"DIALOG_CUTPOINT_SAVEEXIT_0")
8703 BUTTON(actionName, tr(
"Save Cuts and Exit"));
8717 if (!text.isEmpty())
8718 BUTTON(actionName, text);
8730 const QString &actionName = Context.
m_action;
8732 bool result =
false;
8737 result = Context.
m_menu.
Show(Context.
m_node, QDomNode(), *
this, Menu,
false);
8827 if (
prefix ==
"SELECTSUBTITLE_") {
8829 }
else if (
prefix ==
"SELECTRAWTEXT_") {
8831 }
else if (
prefix ==
"SELECTCC708_") {
8833 }
else if (
prefix ==
"SELECTCC608_") {
8835 }
else if (
prefix ==
"SELECTTTC_") {
8837 }
else if (
prefix ==
"SELECTAUDIO_") {
8859 static const std::array<const speed,9> s_speeds {{
8860 { .m_speedX100=0, .m_suffix=
"", .m_trans=tr(
"Adjust")},
8861 { .m_speedX100=50, .m_suffix=
"0.5", .m_trans=tr(
"0.5x")},
8862 { .m_speedX100=90, .m_suffix=
"0.9", .m_trans=tr(
"0.9x")},
8863 {.m_speedX100=100, .m_suffix=
"1.0", .m_trans=tr(
"1.0x")},
8864 {.m_speedX100=110, .m_suffix=
"1.1", .m_trans=tr(
"1.1x")},
8865 {.m_speedX100=120, .m_suffix=
"1.2", .m_trans=tr(
"1.2x")},
8866 {.m_speedX100=130, .m_suffix=
"1.3", .m_trans=tr(
"1.3x")},
8867 {.m_speedX100=140, .m_suffix=
"1.4", .m_trans=tr(
"1.4x")},
8868 {.m_speedX100=150, .m_suffix=
"1.5", .m_trans=tr(
"1.5x")},
8871 for (
const auto & speed : s_speeds)
8893 BUTTON(
"CHANGROUP_ALL_CHANNELS", tr(
"All Channels"));
8894 ChannelGroupList::const_iterator it;
8898 QString
action =
prefix + QString::number(it->m_grpId);
8908 static constexpr std::array<const uint,3> kCasOrd { 0, 2, 1 };
8909 for (
uint csm : kCasOrd)
8926 QString chapter1 = QString(
"%1").arg(i+1, size, 10, QChar{
'0'});
8927 QString chapter2 = QString(
"%1").arg(i+1, 3 , 10, QChar{
'0'});
8929 QString desc = chapter1 + QString(
" (%1)").arg(timestr);
8942 QString angleIdx = QString(
"%1").arg(i, 3, 10, QChar{
'0'});
8957 QString titleIdx = QString(
"%1").arg(i, 3, 10, QChar{
'0'});
8970 QVector <QString> addednames;
8972 for (
auto & input : inputs)
8974 if (input.m_inputId == inputid ||
8975 addednames.contains(input.m_displayName))
8978 addednames += input.m_displayName;
8979 QString
action = QString(
"SWITCHTOINPUT_") +
8980 QString::number(input.m_inputId);
8992 uint sourceid =
info[
"sourceid"].toUInt();
8993 QMap<uint, bool> sourceids;
8995 for (
auto & input : inputs)
8997 if (input.m_sourceId == sourceid ||
8998 sourceids[input.m_sourceId])
9001 sourceids[input.m_sourceId] =
true;
9002 QString
action = QString(
"SWITCHTOINPUT_") +
9003 QString::number(input.m_inputId);
9010 if (actionName ==
"TOGGLEAUDIOSYNC")
9012 BUTTON(actionName, tr(
"Adjust Audio Sync"));
9016 BUTTON(actionName, tr(
"None"));
9018 else if (actionName ==
"DISABLEUPMIX")
9023 BUTTON(actionName, tr(
"Disable Audio Upmixer"));
9026 else if (actionName ==
"ENABLEUPMIX")
9031 BUTTON(actionName, tr(
"Auto Detect"));
9034 else if (actionName ==
"AUTODETECT_FILL")
9041 BUTTON(actionName, tr(
"Auto Detect"));
9044 else if (actionName ==
"TOGGLEMANUALZOOM")
9046 BUTTON(actionName, tr(
"Manual Zoom Mode"));
9048 else if (actionName ==
"DISABLESUBS")
9052 BUTTON(actionName, tr(
"Disable Subtitles"));
9054 else if (actionName ==
"ENABLESUBS")
9058 BUTTON(actionName, tr(
"Enable Subtitles"));
9060 else if (actionName ==
"DISABLEFORCEDSUBS")
9066 BUTTON(actionName, tr(
"Disable Forced Subtitles"));
9069 else if (actionName ==
"ENABLEFORCEDSUBS")
9075 BUTTON(actionName, tr(
"Enable Forced Subtitles"));
9078 else if (actionName ==
"DISABLEEXTTEXT")
9082 BUTTON(actionName, tr(
"Disable External Subtitles"));
9084 else if (actionName ==
"ENABLEEXTTEXT")
9088 BUTTON(actionName, tr(
"Enable External Subtitles"));
9090 else if (actionName ==
"TOGGLETTM")
9093 BUTTON(actionName, tr(
"Toggle Teletext Menu"));
9095 else if (actionName ==
"TOGGLESUBZOOM")
9098 BUTTON(actionName, tr(
"Adjust Subtitle Zoom"));
9100 else if (actionName ==
"TOGGLESUBDELAY")
9106 BUTTON(actionName, tr(
"Adjust Subtitle Delay"));
9109 else if (actionName ==
"PAUSE")
9112 BUTTON2(actionName, tr(
"Play"), tr(
"Pause"));
9114 else if (actionName ==
"TOGGLESTRETCH")
9116 BUTTON(actionName, tr(
"Toggle"));
9118 else if (actionName ==
"TOGGLEBROWSE")
9121 BUTTON(actionName, tr(
"Toggle Browse Mode"));
9123 else if (actionName ==
"CANCELPLAYLIST")
9126 BUTTON(actionName, tr(
"Cancel Playlist"));
9128 else if (actionName ==
"DEBUGOSD")
9130 BUTTON(actionName, tr(
"Playback Data"));
9132 else if (actionName ==
"JUMPFFWD")
9135 BUTTON(actionName, tr(
"Jump Ahead"));
9137 else if (actionName ==
"JUMPRWND")
9140 BUTTON(actionName, tr(
"Jump Back"));
9142 else if (actionName ==
"JUMPTODVDROOTMENU")
9147 BUTTON2(actionName, tr(
"DVD Root Menu"), tr(
"Top menu"));
9150 else if (actionName ==
"JUMPTOPOPUPMENU")
9153 BUTTON(actionName, tr(
"Popup menu"));
9155 else if (actionName ==
"JUMPTODVDTITLEMENU")
9158 BUTTON(actionName, tr(
"DVD Title Menu"));
9160 else if (actionName ==
"JUMPTODVDCHAPTERMENU")
9163 BUTTON(actionName, tr(
"DVD Chapter Menu"));
9165 else if (actionName ==
"PREVCHAN")
9168 BUTTON(actionName, tr(
"Previous Channel"));
9170 else if (actionName ==
"GUIDE")
9172 BUTTON(actionName, tr(
"Program Guide"));
9174 else if (actionName ==
"FINDER")
9176 BUTTON(actionName, tr(
"Program Finder"));
9178 else if (actionName ==
"VIEWSCHEDULED")
9180 BUTTON(actionName, tr(
"Upcoming Recordings"));
9182 else if (actionName ==
"SCHEDULE")
9184 BUTTON(actionName, tr(
"Edit Recording Schedule"));
9186 else if (actionName ==
"DIALOG_JUMPREC_X_0")
9188 BUTTON3(actionName, tr(
"Recorded Program"),
"",
true);
9194 else if (actionName ==
"JUMPPREV")
9211 else if (actionName ==
"EDIT")
9217 BUTTON2(actionName, tr(
"Edit Channel"), tr(
"Edit Recording"));
9220 else if (actionName ==
"TOGGLEAUTOEXPIRE")
9226 tr(
"Turn Auto-Expire OFF"), tr(
"Turn Auto-Expire ON"));
9229 else if (actionName ==
"QUEUETRANSCODE")
9234 BUTTON2(actionName, tr(
"Stop Transcoding"), tr(
"Default"));
9237 else if (actionName ==
"QUEUETRANSCODE_AUTO")
9242 BUTTON(actionName, tr(
"Autodetect"));
9245 else if (actionName ==
"QUEUETRANSCODE_HIGH")
9250 BUTTON(actionName, tr(
"High Quality"));
9253 else if (actionName ==
"QUEUETRANSCODE_MEDIUM")
9258 BUTTON(actionName, tr(
"Medium Quality"));
9261 else if (actionName ==
"QUEUETRANSCODE_LOW")
9266 BUTTON(actionName, tr(
"Low Quality"));
9273 BUTTON(actionName, tr(
"Cast"));
9284 if (!text.isEmpty())
9285 BUTTON(actionName, text);
9345 QString cur_channum = QString();
9348 if (!prev_channum.isEmpty() && prev_channum != cur_channum)
9400 QString text = Menu.
Translate(Node.toElement().attribute(
"text", Menu.
GetName()));
9401 const char* windowtitle {
"???" };
9407 Menu.
Show(Node, Selected, *
this, &
menu);
9408 QDomNode parent = Node.parentNode();
9409 if (!parent.parentNode().isNull())
9413 menu.m_back = { .m_text=
"", .m_data=v };
9422 map.insert(
"title", tr(
"Edit"));
9431 (void)tr(
"Playback Menu");
9432 (void)tr(
"Playback Compact Menu");
9434 (void)tr(
"Select Audio Track");
9435 (void)tr(
"Visualisation");
9437 (void)tr(
"Change Aspect Ratio");
9438 (void)tr(
"Adjust Fill");
9439 (void)tr(
"Adjust Picture");
9441 (void)tr(
"Advanced");
9442 (void)tr(
"Video Scan");
9443 (void)tr(
"Deinterlacer");
9444 (void)tr(
"Subtitles");
9445 (void)tr(
"Select Subtitle");
9446 (void)tr(
"Text Subtitles");
9447 (void)tr(
"Select ATSC CC");
9448 (void)tr(
"Select VBI CC");
9449 (void)tr(
"Select Teletext CC");
9450 (void)tr(
"Playback");
9451 (void)tr(
"Adjust Time Stretch");
9452 (void)tr(
"Picture-in-Picture");
9454 (void)tr(
"Channel Groups");
9455 (void)tr(
"Navigate");
9456 (void)tr(
"Commercial Auto-Skip");
9457 (void)tr(
"Chapter");
9460 (void)tr(
"Schedule");
9462 (void)tr(
"Jump to Program");
9463 (void)tr(
"Switch Input");
9464 (void)tr(
"Switch Source");
9466 (void)tr(
"Begin Transcoding");
9468 (void)tr(
"Recorded");
9469 (void)tr(
"Upcoming");
9472 (void)tr(
"Edit Cut Points");
9473 (void)tr(
"Edit Cut Points (Compact)");
9474 (void)tr(
"Cut List Options");
9482 "menu_playback.xml", tr(
"Playback Menu"),
9483 metaObject()->className(),
"TV Playback");
9485 "menu_playback_compact.xml", tr(
"Playback Compact Menu"),
9486 metaObject()->className(),
"TV Playback");
9498 if (Level < 0 || Level > 1)
9505 .m_message=tr(
"Recorded Program") };
9513 QList<QString> titles_seen;
9519 for (
auto *pi : *infoList)
9521 if (pi->GetRecordingGroup() !=
"LiveTV" || LiveTVInAllPrograms ||
9522 pi->GetRecordingGroup() == currecgroup)
9530 QMap<QString,ProgramList>::const_iterator Iprog;
9534 auto progIndex =
static_cast<uint>(plist.
size());
9535 const QString& group = Iprog.key();
9540 if (progIndex == 1 && Level == 0)
9542 dialog.m_buttons.push_back( {Iprog.key(), QString(
"JUMPPROG %1 0").arg(group) });
9544 else if (progIndex > 1 && Level == 0)
9546 QString act = QString(
"DIALOG_%1_%2_1")
9548 dialog.m_buttons.push_back( {group, act,
true, Selected == group });
9550 else if (Level == 1 && Iprog.key() == Category)
9552 for (
auto pit = plist.
begin(); pit != plist.
end(); ++pit)
9556 if (titles_seen.contains(
p->GetTitle()))
9559 titles_seen.push_back(
p->GetTitle());
9562 for (
auto *q : plist)
9566 if (q->GetTitle() !=
p->GetTitle())
9569 dialog.m_buttons.push_back( { q->GetSubtitle().isEmpty() ?
9570 q->GetTitle() : q->GetSubtitle(),
9571 QString(
"JUMPPROG %1 %2").arg(Iprog.key()).arg(j) });
9579 while (!infoList->empty())
9581 delete infoList->back();
9582 infoList->pop_back();
9587 if (!Category.isEmpty())
9591 dialog.m_back = { .m_text=Category,
9594 else if (Level == 0)
9597 dialog.m_back = { .m_text=
"",
9610 bool recorded = (
ProgInfo.GetFilesize() > 0);
9611 QString table = recorded ?
"recordedcredits" :
"credits";
9618 query.
prepare(QString(
"SELECT role, people.name,"
9619 " roles.name, people.person FROM %1"
9621 " LEFT JOIN people ON"
9622 " credits.person = people.person"
9623 " LEFT JOIN roles ON"
9624 " credits.roleid = roles.roleid"
9625 " WHERE credits.chanid = :CHANID"
9626 " AND credits.starttime = :STARTTIME"
9627 " AND role IN ('guest','actor','guest_star')"
9628 " ORDER BY role, priority;").arg(table));
9633 if (query.
exec() && query.
size() > 0)
9641 role = query.
value(0).toString();
9657 int pid = query.
value(3).toInt();
9658 pname = QString::fromUtf8(query.
value(1)
9659 .toByteArray().constData()) +
9660 "|" + QString::number(pid);
9661 character = QString::fromUtf8(query.
value(2)
9662 .toByteArray().constData());
9664 if (role ==
"actor")
9665 m_actors.append(qMakePair(pname, character));
9666 else if (role ==
"guest_star")
9668 else if (role ==
"guest")
9669 m_guests.append(qMakePair(pname, character));
9676 const QVector<string_pair> & people)
9678 for (
const auto & [actor, role] : std::as_const(people))
9682 dialog.
m_buttons.push_back( {actor.split(
'|')[0],
9683 QString(
"JUMPCAST|%1").arg(actor),
true} );
9687 dialog.
m_buttons.push_back( {QString(
"%1 as %2")
9688 .arg(actor.split(
'|')[0], role),
9689 QString(
"JUMPCAST|%1").arg(actor),
true} );
9707 const QString & category)
9711 if (category.isEmpty())
9713 dialog.m_buttons.push_back( {
"Recorded",
9714 QString(
"JUMPCAST|%1|%2|Recorded").arg(actor).arg(person_id) } );
9715 dialog.m_buttons.push_back( {
"Upcoming",
9716 QString(
"JUMPCAST|%1|%2|Upcoming").arg(actor).arg(person_id) } );
9721 if (category ==
"Upcoming")
9733 QString table =
"recordedcredits";
9735 query.
prepare(QString(
"SELECT chanid, starttime from %1"
9736 " where person = :PERSON"
9737 " ORDER BY starttime;").arg(table));
9740 QDateTime starttime;
9741 if (query.
exec() && query.
size() > 0)
9745 int chanid = query.
value(0).toInt();
9747 auto *pi =
new ProgramInfo(chanid, starttime.toUTC());
9748 if (!pi->GetTitle().isEmpty() &&
9749 pi->GetRecordingGroup() !=
"LiveTV" &&
9750 pi->GetRecordingGroup() !=
"Deleted")
9763 show = pi->GetTitle();
9766 if (!pi->GetSubtitle().isEmpty())
9768 show += QString(
" %1x%2 %3").arg(pi->GetSeason())
9769 .arg(pi->GetEpisode())
9770 .arg(pi->GetSubtitle());
9773 dialog.m_buttons.push_back( {
show,
9774 QString(
"JUMPPROG %1 %2").arg(actor).arg(++idx) });
9791 if (!message.isEmpty())
9804 desc = tr(
"Auto-Expire OFF");
9809 desc = tr(
"Auto-Expire ON");
9814 if (!desc.isEmpty())
9830 if (!desc.isEmpty())
9839 if (!Desc.isEmpty())
9855 for (
const auto&
action : std::as_const(Actions))
9857 if (!
action.startsWith(
"JUMPPROG"))
9861 QString key =
action.section(
" ",1,-2);
9862 uint index =
action.section(
" ",-1,-1).toUInt(&ok);
9879 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to locate jump to program '%1' @ %2")
9880 .arg(key,
action.section(
" ",-1,-1)));
9902 QTimer::singleShot(0,
this, Jump);
9910 LOG(VB_GENERAL, LOG_ERR,
"Failed to open jump to program GUI");
9918 std::chrono::minutes mins { 0min };
9941 if (Time.length() > 11)
9943 bool intRead =
false;
9944 mins = std::chrono::minutes(Time.right(Time.length() - 11).toUInt(&intRead));
9957 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time " + Time);
9962 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid time string " + Time);
9974 out = tr(
"Sleep") +
" " + QString::number(mins.count());
9976 out = tr(
"Sleep") +
" " +
kSleepTimes[0].dispString;
9987 errorText = tr(
"MythTV is already using all available "
9988 "inputs for the channel you selected. "
9989 "If you want to watch an in-progress recording, "
9990 "select one from the playback menu. If you "
9991 "want to watch Live TV, cancel one of the "
9992 "in-progress recordings from the delete "
9996 errorText = tr(
"Error: MythTV is using all inputs, "
9997 "but there are no active recordings?");
10000 errorText = tr(
"MythTV has no capture cards defined. "
10001 "Please run the mythtv-setup program.");
10007 .m_message=errorText,
10009 .m_buttons={{ tr(
"OK"),
"DIALOG_INFO_X_X" }}});
10142 else if (!dvd->StartOfTitle())
10148 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10149 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10172 bool in_menu = dvd->IsInMenu();
10173 if (in_still && !dvd->NumMenuButtons())
10175 dvd->SkipStillFrame();
10178 else if (!dvd->EndOfTitle() && !in_still && !in_menu)
10182 else if (!in_still && !in_menu)
10184 std::chrono::seconds titleLength = dvd->GetTotalTimeOfTitle();
10185 std::chrono::seconds
chapterLength = dvd->GetChapterLength();
10186 std::chrono::seconds currentTime = dvd->GetCurrentTime();
10231 bool allowed =
false;
10254 videotype = tr(
"Live TV");
10256 videotype = tr(
"this DVD");
10260 videotype = tr(
"this Video");
10263 if (videotype.isEmpty())
10264 videotype = tr(
"this recording");
10267 .m_message=tr(
"You are exiting %1").arg(videotype) };
10269 dialog.m_buttons.push_back({tr(
"Exit %1").arg(videotype),
ACTION_STOP});
10271 dialog.m_buttons.push_back({tr(
"Exit Without Saving"),
"DIALOG_VIDEOEXIT_CLEARLASTPLAYEDPOSITION_0"});
10274 dialog.m_buttons.push_back({tr(
"Delete this recording"),
"DIALOG_VIDEOEXIT_CONFIRMDELETE_0"});
10276 dialog.m_buttons.push_back({tr(
"Keep watching"),
"DIALOG_VIDEOEXIT_KEEPWATCHING_0"});
10277 dialog.m_back = { .m_text=
"",
10278 .m_data=
"DIALOG_VIDEOEXIT_KEEPWATCHING_0",
10280 emit ChangeOSDDialog(dialog);
10282 if (m_videoExitDialogTimerId)
10283 KillTimer(m_videoExitDialogTimerId);
10284 m_videoExitDialogTimerId = StartTimer(kVideoExitDialogTimeout, __LINE__);
10294 LOG(VB_GENERAL, LOG_ERR,
"It is unsafe to delete at the moment");
10302 LOG(VB_GENERAL, LOG_ERR,
"This program cannot be deleted at this time.");
10309 QString message = tr(
"Cannot delete program ") + QString(
"%1 ").arg(pginfo.
GetTitle());
10312 message += QString(
"\"%1\" ").arg(pginfo.
GetSubtitle());
10316 message += tr(
"because it is not a recording.");
10320 message += tr(
"because it is in use by");
10323 for (
int i = 0; (i + 2) < byWho.size(); i += 3)
10329 message +=
" " + byWho[i+2];
10334 .m_message=message,
10336 .m_buttons={{ tr(
"OK"),
"DIALOG_DELETE_OK_0" }},
10337 .m_back={ .m_text=
"", .m_data=
"DIALOG_DELETE_OK_0", .m_exit=
true }});
10360 QString message = QString(
"%1\n%2\n%3")
10361 .arg(Title, infoMap[
"title"], infoMap[
"timedate"]);
10367 .m_message=message };
10368 if (Title ==
"End Of Recording")
10370 dialog.m_buttons.push_back({tr(
"Delete it, but allow it to re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10371 dialog.m_buttons.push_back({tr(
"Delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10372 dialog.m_buttons.push_back({tr(
"Save it so I can watch it again"),
ACTION_STOP,
false,
true});
10376 dialog.m_buttons.push_back({tr(
"Yes, and allow re-record"),
"DIALOG_VIDEOEXIT_DELETEANDRERECORD_0"});
10377 dialog.m_buttons.push_back({tr(
"Yes, delete it"),
"DIALOG_VIDEOEXIT_JUSTDELETE_0"});
10378 dialog.m_buttons.push_back({tr(
"No, keep it"),
ACTION_STOP,
false,
true});
10380 dialog.m_back = { .m_text=
"",
10381 .m_data=
"DIALOG_PLAY_0_0",
10406 if (
Action ==
"DELETEANDRERECORD" && delete_ok)
10413 else if (
Action ==
"JUSTDELETE" && delete_ok)
10419 else if (
Action ==
"CONFIRMDELETE")
10424 else if (
Action ==
"KEEPWATCHING" && !near_end)
10428 else if (
Action ==
"CLEARLASTPLAYEDPOSITION")
10507 bool paused =
false;
10559 case Qt::ApplicationState::ApplicationSuspended:
10561 LOG(VB_GENERAL, LOG_NOTICE,
"Exiting playback on app suspecnd");
10585 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)
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
static const std::vector< SleepTimerInfo > kSleepTimes
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
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
static int GetActiveChannelGroupId()
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)
QVector< string_pair > m_guestStars
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
std::array< QStringList, kTrackTypeCount > m_tvmTracks
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)
std::array< int, kTrackTypeCount > m_tvmCurtrack
bool m_dbContinueEmbedded
void ChangeTimeStretch(int Dir, bool AllowEdit=true)
bool TimeStretchHandleAction(const QStringList &Actions)
static const std::chrono::milliseconds kEndOfPlaybackCheckFrequency
static EMBEDRETURNVOID RunViewScheduledPtr
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)
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::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 std::strong_ordering 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
std::vector< ProgramInfo * > * RemoteGetRecordedList(int sort)
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)
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
@ kStartTVIgnoreLastPlayPos
@ kStartTVIgnoreProgStart
@ kStartTVByNetworkCommand
void(*)(TV *, bool, bool) EMBEDRETURNVOIDFINDER
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)
@ kAdjustFill_AutoDetect_DefaultHalf
@ kAdjustFill_AutoDetect_DefaultOff
PictureAttributeSupported
@ kPictureAttributeSupported_Colour
@ kPictureAttributeSupported_Volume
@ kPictureAttributeSupported_Brightness
@ kPictureAttributeSupported_Hue
@ kPictureAttributeSupported_Contrast
@ kPictureAttributeSupported_None
@ kDisplayRawTextSubtitle
@ kDisplayNUVTeletextCaptions
@ kDisplayTeletextCaptions
@ 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.