eServiceReference, iRecordableService, quitMainloop
from Components.config import config
+from Components.UsageConfig import defaultMoviePath
from Components.TimerSanityCheck import TimerSanityCheck
from Screens.MessageBox import MessageBox
if config.recording.ascii_filenames.value:
filename = ASCIItranslit.legacyEncode(filename)
- if self.dirname and not Directories.fileExists(self.dirname, 'w'):
- self.dirnameHadToFallback = True
- self.Filename = Directories.getRecordingFilename(filename, None)
+ if not self.dirname or not Directories.fileExists(self.dirname, 'w'):
+ if self.dirname:
+ self.dirnameHadToFallback = True
+ dirname = defaultMoviePath()
else:
- self.Filename = Directories.getRecordingFilename(filename, self.dirname)
+ dirname = self.dirname
+ self.Filename = Directories.getRecordingFilename(filename, dirname)
self.log(0, "Filename calculated as: '%s'" % self.Filename)
#begin_date + " - " + service_name + description)
<item level="1" text="Device Setup..." entryID="device_setup"><screen module="NetworkSetup" screen="NetworkAdapterSelection"/></item>
<item level="1" text="Nameserver Setup..." entryID="dns_setup"><screen module="NetworkSetup" screen="NameserverSetup"/></item>
</menu>-->
- <item level="2" text="Timeshift path..." entryId="timeshift_path"><screen module="LocationBox" screen="TimeshiftLocationBox" /></item>
+ <item level="2" text="Recording paths..." entryId="RecordPaths"><screen module="RecordPaths" screen="RecordPathsSettings" /></item>
</menu>
<item weight="10" level="1" text="Common Interface" entryID="ci_setup" requires="CommonInterface"><screen module="Ci" screen="CiSelection" /></item>
<item weight="15" level="0" text="Parental control" entryID="parental_setup"><screen module="ParentalControlSetup" screen="ParentalControlSetup" /></item>
int eTSMPEGDecoder::m_pcm_delay=-1,
eTSMPEGDecoder::m_ac3_delay=-1;
-RESULT eTSMPEGDecoder::setPCMDelay(int delay)
+RESULT eTSMPEGDecoder::setHwPCMDelay(int delay)
{
- if (m_decoder == 0 && delay != m_pcm_delay )
+ if (delay != m_pcm_delay )
{
FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
if (fp)
return -1;
}
-RESULT eTSMPEGDecoder::setAC3Delay(int delay)
+RESULT eTSMPEGDecoder::setHwAC3Delay(int delay)
{
- if ( m_decoder == 0 && delay != m_ac3_delay )
+ if ( delay != m_ac3_delay )
{
FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
if (fp)
return -1;
}
+
+RESULT eTSMPEGDecoder::setPCMDelay(int delay)
+{
+ return m_decoder == 0 ? setHwPCMDelay(delay) : -1;
+}
+
+RESULT eTSMPEGDecoder::setAC3Delay(int delay)
+{
+ return m_decoder == 0 ? setHwAC3Delay(delay) : -1;
+}
+
eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder)
: m_demux(demux),
m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1),
int getVideoProgressive();
int getVideoFrameRate();
int getVideoAspect();
+ static RESULT setHwPCMDelay(int delay);
+ static RESULT setHwAC3Delay(int delay);
};
#endif
continue;
}
- size_t iframe_len;
- /* try to align to iframe */
- int direction = pts < 0 ? -1 : 1;
- m_tstools.findFrame(offset, iframe_len, direction);
-
- eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
+ eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
}
off_t last = 0;
off_t last2 = 0;
pts_t lastc = 0;
+ ts += 1; // Add rounding error margin
for (std::map<off_t, pts_t>::const_iterator i(m_access_points.begin()); i != m_access_points.end(); ++i)
{
pts_t delta = getDelta(i->first);
int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int frame_types)
{
- int nr_frames = 0;
+ int nr_frames, direction;
// eDebug("trying to move %d frames at %llx", distance, offset);
frame_types = frametypeI; /* TODO: intelligent "allow IP frames when not crossing an I-Frame */
- int direction = distance > 0 ? 0 : -1;
- distance = abs(distance);
-
off_t new_offset = offset;
size_t new_len = len;
int first = 1;
+ if (distance > 0) {
+ direction = 0;
+ nr_frames = 0;
+ } else {
+ direction = -1;
+ nr_frames = -1;
+ distance = -distance+1;
+ }
while (distance > 0)
{
int dir = direction;
// eDebug("we moved %d, %d to go frames (now at %llx)", dir, distance, new_offset);
- if (distance >= 0 || first)
+ if (distance >= 0 || direction == 0)
{
first = 0;
offset = new_offset;
len = new_len;
nr_frames += abs(dir);
+ }
+ else if (first) {
+ first = 0;
+ offset = new_offset;
+ len = new_len;
+ nr_frames += abs(dir) + distance; // never jump forward during rewind
}
}
from MenuList import MenuList
from Components.Harddisk import harddiskmanager
-from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename
+from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename, fileExists
from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \
eServiceReference, eServiceCenter, gFont
directories.sort()
files.sort()
else:
- if os_path.exists(directory):
- files = listdir(directory)
+ if fileExists(directory):
+ try:
+ files = listdir(directory)
+ except:
+ files = []
files.sort()
tmpfiles = files[:]
for x in tmpfiles:
directories.sort()
files.sort()
else:
- if os_path.exists(directory):
- files = listdir(directory)
+ if fileExists(directory):
+ try:
+ files = listdir(directory)
+ except:
+ files = []
files.sort()
tmpfiles = files[:]
for x in tmpfiles:
# any access has been made to the disc. If there has been no access over a specifed time,
# we set the hdd into standby.
def readStats(self):
- l = readFile("/sys/block/%s/stat" % self.device)
+ try:
+ l = open("/sys/block/%s/stat" % self.device).read()
+ except IOError:
+ return -1,-1
(nr_read, _, _, _, nr_write) = l.split()[:5]
return int(nr_read), int(nr_write)
l = sum(stats)
print "sum", l, "prev_sum", self.last_stat
- if l != self.last_stat: # access
+ if l != self.last_stat and l >= 0: # access
print "hdd was accessed since previous check!"
self.last_stat = l
self.last_access = t
lnb_choices = {
"universal_lnb": _("Universal LNB"),
-# "unicable": _("Unicable"),
+ "unicable": _("Unicable"),
"c_band": _("C-Band"),
"user_defined": _("User defined")}
from Components.Harddisk import harddiskmanager
from config import ConfigSubsection, ConfigYesNo, config, ConfigSelection, ConfigText, ConfigNumber, ConfigSet, ConfigLocations
+from Tools.Directories import resolveFilename, SCOPE_HDD
from enigma import Misc_Options, setTunerTypePriorityOrder;
from SystemInfo import SystemInfo
import os
("standard", _("standard")), ("swap", _("swap PiP and main picture")),
("swapstop", _("move PiP to main picture")), ("stop", _("stop PiP")) ])
+ config.usage.default_path = ConfigText(default = resolveFilename(SCOPE_HDD))
+ config.usage.timer_path = ConfigText(default = "<default>")
+ config.usage.instantrec_path = ConfigText(default = "<default>")
+ config.usage.timeshift_path = ConfigText(default = "/media/hdd/")
config.usage.allowed_timeshift_paths = ConfigLocations(default = ["/media/hdd/"])
- config.usage.timeshift_path = ConfigText(default = "/media/hdd")
config.usage.on_movie_start = ConfigSelection(default = "ask", choices = [
("ask", _("Ask user")), ("resume", _("Resume from last position")), ("beginning", _("Start from the beginning")) ])
def TunerTypePriorityOrderChanged(configElement):
setTunerTypePriorityOrder(int(configElement.value))
- config.usage.alternatives_priority.addNotifier(TunerTypePriorityOrderChanged)
+ config.usage.alternatives_priority.addNotifier(TunerTypePriorityOrderChanged, immediate_feedback=False)
def setHDDStandby(configElement):
for hdd in harddiskmanager.HDDList():
hdd[1].setIdleTime(int(configElement.value))
- config.usage.hdd_standby.addNotifier(setHDDStandby)
+ config.usage.hdd_standby.addNotifier(setHDDStandby, immediate_feedback=False)
def set12VOutput(configElement):
if configElement.value == "on":
Misc_Options.getInstance().set_12V_output(1)
elif configElement.value == "off":
Misc_Options.getInstance().set_12V_output(0)
- config.usage.output_12V.addNotifier(set12VOutput)
+ config.usage.output_12V.addNotifier(set12VOutput, immediate_feedback=False)
SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output()
defval = str(x)
break
sel.setChoices(map(str, choices), defval)
+
+def preferredPath(path):
+ if config.usage.setup_level.index < 2 or path == "<default>":
+ return None # config.usage.default_path.value, but delay lookup until usage
+ elif path == "<current>":
+ return config.movielist.last_videodir.value
+ elif path == "<timer>":
+ return config.movielist.last_timer_videodir.value
+ else:
+ return path
+
+def preferredTimerPath():
+ return preferredPath(config.usage.timer_path.value)
+
+def preferredInstantRecordPath():
+ return preferredPath(config.usage.instantrec_path.value)
+
+def defaultMoviePath():
+ return config.usage.default_path.value
+
from enigma import getPrevAsciiCode
from Tools.NumericalTextInput import NumericalTextInput
-from Tools.Directories import resolveFilename, SCOPE_CONFIG
+from Tools.Directories import resolveFilename, SCOPE_CONFIG, fileExists
from Components.Harddisk import harddiskmanager
from copy import copy as copy_copy
from os import path as os_path
self.default = default
self.locations = []
self.mountpoints = []
- harddiskmanager.on_partition_list_change.append(self.mountpointsChanged)
self.value = default[:]
def setValue(self, value):
locations = [[x, None, False, False] for x in tmp]
self.refreshMountpoints()
for x in locations:
- if os_path.exists(x[0]):
+ if fileExists(x[0]):
x[1] = self.getMountpoint(x[0])
x[2] = True
self.locations = locations
return False
return self.tostring([x[0] for x in locations]) != sv
- def mountpointsChanged(self, action, dev):
- print "Mounts changed: ", action, dev
- mp = dev.mountpoint+"/"
- if action == "add":
- self.addedMount(mp)
- elif action == "remove":
- self.removedMount(mp)
- self.refreshMountpoints()
-
def addedMount(self, mp):
for x in self.locations:
if x[1] == mp:
x[2] = True
- elif x[1] == None and os_path.exists(x[0]):
+ elif x[1] == None and fileExists(x[0]):
x[1] = self.getMountpoint(x[0])
x[2] = True
x[2] = False
def refreshMountpoints(self):
- self.mountpoints = [p.mountpoint + "/" for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
+ self.mountpoints = [p.mountpoint for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
self.mountpoints.sort(key = lambda x: -len(x))
def checkChangedMountpoints(self):
from Components.MultiContent import MultiContentEntryText
from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
from Components.VideoWindow import VideoWindow
+from Components.Label import Label
from Screens.InfoBarGenerics import InfoBarSeek, InfoBarCueSheetSupport
from Components.GUIComponent import GUIComponent
from enigma import eListboxPythonMultiContent, eListbox, gFont, iPlayableService, RT_HALIGN_RIGHT
<widget source="session.CurrentService" render="Label" position="135,405" size="450,50" font="Regular;22" halign="center" valign="center">
<convert type="ServiceName">Name</convert>
</widget>
- <widget source="session.CurrentService" render="Label" position="50,450" zPosition="1" size="620,25" font="Regular;20" halign="center" valign="center">
+ <widget source="session.CurrentService" render="Label" position="320,450" zPosition="1" size="420,25" font="Regular;20" halign="left" valign="center">
<convert type="ServicePosition">Position,Detailed</convert>
</widget>
- <eLabel position="62,98" size="179,274" backgroundColor="#505555" />
- <eLabel position="64,100" size="175,270" backgroundColor="#000000" />
- <widget source="cutlist" position="64,100" zPosition="1" size="175,270" scrollbarMode="showOnDemand" transparent="1" render="Listbox" >
+ <widget name="SeekState" position="210,450" zPosition="1" size="100,25" halign="right" font="Regular;20" valign="center" />
+ <eLabel position="48,98" size="204,274" backgroundColor="#505555" />
+ <eLabel position="50,100" size="200,270" backgroundColor="#000000" />
+ <widget source="cutlist" position="50,100" zPosition="1" size="200,270" scrollbarMode="showOnDemand" transparent="1" render="Listbox" >
<convert type="TemplatedMultiContent">
{"template": [
MultiContentEntryText(size=(125, 20), text = 1, backcolor = MultiContentTemplateColor(3)),
self["Timeline"] = ServicePositionGauge(self.session.nav)
self["cutlist"] = List(self.getCutlist())
self["cutlist"].onSelectionChanged.append(self.selectionChanged)
+ self["SeekState"] = Label()
+ self.onPlayStateChanged.append(self.updateStateLabel)
+ self.updateStateLabel(self.seekstate)
self["Video"] = VideoWindow(decoder = 0)
})
# to track new entries we save the last version of the cutlist
- self.last_cuts = [ ]
+ self.last_cuts = self.getCutlist()
self.cut_start = None
+ self.inhibit_seek = False
self.onClose.append(self.__onClose)
def __onClose(self):
self.session.nav.playService(self.old_service)
+ def updateStateLabel(self, state):
+ self["SeekState"].setText(state[3].strip())
+
def showTutorial(self):
if not self.tutorial_seen:
self.tutorial_seen = True
return r
def selectionChanged(self):
- where = self["cutlist"].getCurrent()
- if where is None:
- print "no selection"
- return
- pts = where[0][0]
- seek = self.getSeek()
- if seek is None:
- print "no seek"
- return
- seek.seekTo(pts)
+ if not self.inhibit_seek:
+ where = self["cutlist"].getCurrent()
+ if where is None:
+ print "no selection"
+ return
+ pts = where[0][0]
+ seek = self.getSeek()
+ if seek is None:
+ print "no seek"
+ return
+ seek.seekTo(pts)
def refillList(self):
print "cue sheet changed, refilling"
self.downloadCuesheet()
- # get the first changed entry, and select it
+ # get the first changed entry, counted from the end, and select it
new_list = self.getCutlist()
self["cutlist"].list = new_list
- for i in range(min(len(new_list), len(self.last_cuts))):
- if new_list[i] != self.last_cuts[i]:
- self["cutlist"].setIndex(i)
+ l1 = len(new_list)
+ l2 = len(self.last_cuts)
+ for i in range(min(l1, l2)):
+ if new_list[l1-i-1] != self.last_cuts[l2-i-1]:
+ self["cutlist"].setIndex(l1-i-1)
break
self.last_cuts = new_list
def getStateForPosition(self, pos):
- state = 0 # in
-
- # when first point is "in", the beginning is "out"
- if len(self.cut_list) and self.cut_list[0][1] == 0:
- state = 1
-
+ state = -1
for (where, what) in self.cut_list:
- if where < pos:
- if what == 0: # in
- state = 0
- elif what == 1: # out
+ if what in [0, 1]:
+ if where < pos:
+ state = what
+ elif where == pos:
state = 1
+ elif state == -1:
+ state = 1 - what
+ if state == -1:
+ state = 0
return state
def showMenu(self):
in_after = None
for (where, what) in self.cut_list:
- if what == 1 and where < self.context_position: # out
+ if what == 1 and where <= self.context_position: # out
out_before = (where, what)
elif what == 0 and where < self.context_position: # in, before out
out_before = None
- elif what == 0 and where > self.context_position and in_after is None:
+ elif what == 0 and where >= self.context_position and in_after is None:
in_after = (where, what)
if out_before is not None:
if in_after is not None:
self.cut_list.remove(in_after)
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_MARK:
self.__addMark()
elif result == CutListContextMenu.RET_DELETEMARK:
self.cut_list.remove(self.context_nearest_mark)
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_REMOVEBEFORE:
# remove in/out marks before current position
for (where, what) in self.cut_list[:]:
self.cut_list.remove((where, what))
# add 'in' point
bisect.insort(self.cut_list, (self.context_position, 0))
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_REMOVEAFTER:
# remove in/out marks after current position
for (where, what) in self.cut_list[:]:
self.cut_list.remove((where, what))
# add 'out' point
bisect.insort(self.cut_list, (self.context_position, 1))
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_GRABFRAME:
self.grabFrame()
# 'None' is magic to start at the list of mountpoints
defaultDir = config.mediaplayer.defaultDir.getValue()
- self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|mov)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
+ self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|m2ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|mov)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
self["filelist"] = self.filelist
self.playlist = MyPlayList()
from Components.EpgList import EPGList, EPG_TYPE_SINGLE, EPG_TYPE_SIMILAR, EPG_TYPE_MULTI
from Components.ActionMap import ActionMap
from Components.TimerSanityCheck import TimerSanityCheck
+from Components.UsageConfig import preferredTimerPath
from Components.Sources.ServiceEvent import ServiceEvent
from Components.Sources.Event import Event
from Screens.TimerEdit import TimerSanityConflict
self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
break
else:
- newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+ newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, dirname = preferredTimerPath(), *parseEvent(event))
self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
def finishedAdd(self, answer):
from Components.Label import Label
from Components.ScrollLabel import ScrollLabel
from Components.TimerList import TimerList
+from Components.UsageConfig import preferredTimerPath
from enigma import eEPGCache, eTimer, eServiceReference
from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
from TimerEntry import TimerEntry
self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
break
else:
- newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, *parseEvent(self.event))
+ newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, dirname = preferredTimerPath(), *parseEvent(self.event))
self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
def finishedAdd(self, answer):
return
if answer in ("quit", "quitanddeleteconfirmed"):
- config.movielist.last_videodir.cancel()
self.close()
elif answer == "movielist":
ref = self.session.nav.getCurrentlyPlayingServiceReference()
from Components.Sources.Boolean import Boolean
from Components.config import config, ConfigBoolean, ConfigClock
from Components.SystemInfo import SystemInfo
+from Components.UsageConfig import preferredInstantRecordPath, defaultMoviePath
from EpgSelection import EPGSelection
from Plugins.Plugin import PluginDescriptor
from ServiceReference import ServiceReference
from Tools import Notifications
-from Tools.Directories import SCOPE_HDD, resolveFilename, fileExists
+from Tools.Directories import fileExists
from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInformation, \
iPlayableService, eServiceReference, eEPGCache
iPlayableService.evSOF: self.__evSOF,
})
- self.minSpeedBackward = useSeekBackHack and 16 or 0
-
class InfoBarSeekActionMap(HelpableActionMap):
def __init__(self, screen, *args, **kwargs):
HelpableActionMap.__init__(self, screen, *args, **kwargs)
self.__seekableStatusChanged()
def makeStateForward(self, n):
- minspeed = config.seek.stepwise_minspeed.value
- repeat = int(config.seek.stepwise_repeat.value)
- if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
- return (0, n * repeat, repeat, ">> %dx" % n)
- else:
+# minspeed = config.seek.stepwise_minspeed.value
+# repeat = int(config.seek.stepwise_repeat.value)
+# if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+# return (0, n * repeat, repeat, ">> %dx" % n)
+# else:
return (0, n, 0, ">> %dx" % n)
def makeStateBackward(self, n):
- minspeed = config.seek.stepwise_minspeed.value
- repeat = int(config.seek.stepwise_repeat.value)
- if self.minSpeedBackward and n < self.minSpeedBackward:
- r = (self.minSpeedBackward - 1)/ n + 1
- if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
- r = max(r, repeat)
- return (0, -n * r, r, "<< %dx" % n)
- elif minspeed != "Never" and n >= int(minspeed) and repeat > 1:
- return (0, -n * repeat, repeat, "<< %dx" % n)
- else:
+# minspeed = config.seek.stepwise_minspeed.value
+# repeat = int(config.seek.stepwise_repeat.value)
+# if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+# return (0, -n * repeat, repeat, "<< %dx" % n)
+# else:
return (0, -n, 0, "<< %dx" % n)
def makeStateSlowMotion(self, n):
if config.seek.on_pause.value == "play":
self.unPauseService()
elif config.seek.on_pause.value == "step":
- self.doSeekRelative(0)
+ self.doSeekRelative(1)
elif config.seek.on_pause.value == "last":
self.setSeekState(self.lastseekstate)
self.lastseekstate = self.SEEK_STATE_PLAY
self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
self.doSeekRelative(-6)
elif seekstate == self.SEEK_STATE_PAUSE:
- self.doSeekRelative(-3)
+ self.doSeekRelative(-1)
elif self.isStateForward(seekstate):
speed = seekstate[1]
if seekstate[2]:
if isinstance(serviceref, eServiceReference):
serviceref = ServiceReference(serviceref)
- recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = config.movielist.last_videodir.value)
+ recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = preferredInstantRecordPath())
recording.dontSave = True
if event is None or limitEvent == False:
self.session.nav.RecordTimer.timeChanged(entry)
def instantRecord(self):
- dir = config.movielist.last_videodir.value
- if not fileExists(dir, 'w'):
- dir = resolveFilename(SCOPE_HDD)
+ dir = preferredInstantRecordPath()
+ if not dir or not fileExists(dir, 'w'):
+ dir = defaultMoviePath()
try:
stat = os_stat(dir)
except:
else:
self["filelist"].refresh()
self.removeBookmark(name, True)
+ val = self.realBookmarks and self.realBookmarks.value
+ if val and name in val:
+ val.remove(name)
+ self.realBookmarks.value = val
+ self.realBookmarks.save()
def up(self):
self[self.currList].up()
SubtitleDisplay.py SubservicesQuickzap.py ParentalControlSetup.py NumericalTextInputHelpDialog.py \
SleepTimerEdit.py Ipkg.py RdsDisplay.py Globals.py DefaultWizard.py \
SessionGlobals.py LocationBox.py WizardLanguage.py TaskView.py Rc.py VirtualKeyBoard.py \
- TextBox.py FactoryReset.py
+ TextBox.py FactoryReset.py RecordPaths.py
from Components.Pixmap import Pixmap
from Components.Label import Label
from Components.PluginComponent import plugins
-from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations
+from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations, ConfigSet
from Components.Sources.ServiceEvent import ServiceEvent
+from Components.UsageConfig import defaultMoviePath
from Plugins.Plugin import PluginDescriptor
config.movielist.videodirs = ConfigLocations(default=[resolveFilename(SCOPE_HDD)])
config.movielist.first_tags = ConfigText(default="")
config.movielist.second_tags = ConfigText(default="")
+config.movielist.last_selected_tags = ConfigSet([], default=[])
def setPreferredTagEditor(te):
HelpableScreen.__init__(self)
self.tags = [ ]
- self.selected_tags = None
+ if selectedmovie:
+ self.selected_tags = config.movielist.last_selected_tags.value
+ else:
+ self.selected_tags = None
self.selected_tags_ele = None
self.movemode = False
self["DescriptionBorder"] = Pixmap()
self["DescriptionBorder"].hide()
- if not pathExists(config.movielist.last_videodir.value):
- config.movielist.last_videodir.value = resolveFilename(SCOPE_HDD)
+ if not fileExists(config.movielist.last_videodir.value):
+ config.movielist.last_videodir.value = defaultMoviePath()
config.movielist.last_videodir.save()
self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + config.movielist.last_videodir.value)
self.close(None)
def saveconfig(self):
+ config.movielist.last_selected_tags.value = self.selected_tags
config.movielist.moviesort.save()
config.movielist.listtype.save()
config.movielist.description.save()
self["list"].setSortType(type)
def reloadList(self, sel = None, home = False):
- if not pathExists(config.movielist.last_videodir.value):
- path = resolveFilename(SCOPE_HDD)
+ if not fileExists(config.movielist.last_videodir.value):
+ path = defaultMoviePath()
config.movielist.last_videodir.value = path
config.movielist.last_videodir.save()
self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + path)
def gotFilename(self, res):
if res is not None and res is not config.movielist.last_videodir.value:
- if pathExists(res):
+ if fileExists(res):
config.movielist.last_videodir.value = res
config.movielist.last_videodir.save()
self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + res)
def showTagsN(self, tagele):
if not self.tags:
self.showTagWarning()
- elif not tagele or self.selected_tags_ele == tagele or not tagele.value in self.tags:
+ elif not tagele or tagele.value in self.selected_tags or not tagele.value in self.tags:
self.showTagsMenu(tagele)
else:
self.selected_tags_ele = tagele
--- /dev/null
+from Screens.Screen import Screen
+from Screens.LocationBox import MovieLocationBox, TimeshiftLocationBox
+from Screens.MessageBox import MessageBox
+from Components.Label import Label
+from Components.config import config, ConfigSelection, getConfigListEntry, configfile
+from Components.ConfigList import ConfigListScreen
+from Components.ActionMap import ActionMap
+from Tools.Directories import fileExists
+
+
+class RecordPathsSettings(Screen,ConfigListScreen):
+ skin = """
+ <screen name="RecordPathsSettings" position="160,150" size="450,200" title="Recording paths">
+ <ePixmap pixmap="skin_default/buttons/red.png" position="10,0" size="140,40" alphatest="on" />
+ <ePixmap pixmap="skin_default/buttons/green.png" position="300,0" size="140,40" alphatest="on" />
+ <widget source="key_red" render="Label" position="10,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+ <widget source="key_green" render="Label" position="300,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+ <widget name="config" position="10,44" size="430,146" />
+ </screen>"""
+
+ def __init__(self, session):
+ from Components.Sources.StaticText import StaticText
+ Screen.__init__(self, session)
+ self["key_red"] = StaticText(_("Cancel"))
+ self["key_green"] = StaticText(_("Save"))
+
+ ConfigListScreen.__init__(self, [])
+ self.initConfigList()
+
+ self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
+ {
+ "green": self.save,
+ "red": self.cancel,
+ "cancel": self.cancel,
+ "ok": self.ok,
+ }, -2)
+
+ def checkReadWriteDir(self, configele):
+ print "checkReadWrite: ", configele.value
+ if configele.value in [x[0] for x in self.styles] or fileExists(configele.value, "w"):
+ configele.last_value = configele.value
+ return True
+ else:
+ dir = configele.value
+ configele.value = configele.last_value
+ self.session.open(
+ MessageBox,
+ _("The directory %s is not writable.\nMake sure you select a writable directory instead.")%dir,
+ type = MessageBox.TYPE_ERROR
+ )
+ return False
+
+ def initConfigList(self):
+ self.styles = [ ("<default>", _("<Default movie location>")), ("<current>", _("<Current movielist location>")), ("<timer>", _("<Last timer location>")) ]
+ styles_keys = [x[0] for x in self.styles]
+ tmp = config.movielist.videodirs.value
+ default = config.usage.default_path.value
+ if default not in tmp:
+ tmp = tmp[:]
+ tmp.append(default)
+ print "DefaultPath: ", default, tmp
+ self.default_dirname = ConfigSelection(default = default, choices = tmp)
+ tmp = config.movielist.videodirs.value
+ default = config.usage.timer_path.value
+ if default not in tmp and default not in styles_keys:
+ tmp = tmp[:]
+ tmp.append(default)
+ print "TimerPath: ", default, tmp
+ self.timer_dirname = ConfigSelection(default = default, choices = self.styles+tmp)
+ tmp = config.movielist.videodirs.value
+ default = config.usage.instantrec_path.value
+ if default not in tmp and default not in styles_keys:
+ tmp = tmp[:]
+ tmp.append(default)
+ print "InstantrecPath: ", default, tmp
+ self.instantrec_dirname = ConfigSelection(default = default, choices = self.styles+tmp)
+ default = config.usage.timeshift_path.value
+ tmp = config.usage.allowed_timeshift_paths.value
+ if default not in tmp:
+ tmp = tmp[:]
+ tmp.append(default)
+ print "TimeshiftPath: ", default, tmp
+ self.timeshift_dirname = ConfigSelection(default = default, choices = tmp)
+ self.default_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+ self.timer_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+ self.instantrec_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+ self.timeshift_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+
+ self.list = []
+ if config.usage.setup_level.index >= 2:
+ self.default_entry = getConfigListEntry(_("Default movie location"), self.default_dirname)
+ self.list.append(self.default_entry)
+ self.timer_entry = getConfigListEntry(_("Timer record location"), self.timer_dirname)
+ self.list.append(self.timer_entry)
+ self.instantrec_entry = getConfigListEntry(_("Instant record location"), self.instantrec_dirname)
+ self.list.append(self.instantrec_entry)
+ else:
+ self.default_entry = getConfigListEntry(_("Movie location"), self.default_dirname)
+ self.list.append(self.default_entry)
+ self.timeshift_entry = getConfigListEntry(_("Timeshift location"), self.timeshift_dirname)
+ self.list.append(self.timeshift_entry)
+ self["config"].setList(self.list)
+
+ def ok(self):
+ currentry = self["config"].getCurrent()
+ self.lastvideodirs = config.movielist.videodirs.value
+ self.lasttimeshiftdirs = config.usage.allowed_timeshift_paths.value
+ if config.usage.setup_level.index >= 2:
+ txt = _("Default movie location")
+ else:
+ txt = _("Movie location")
+ if currentry == self.default_entry:
+ self.entrydirname = self.default_dirname
+ self.session.openWithCallback(
+ self.dirnameSelected,
+ MovieLocationBox,
+ txt,
+ self.default_dirname.value
+ )
+ elif currentry == self.timer_entry:
+ self.entrydirname = self.timer_dirname
+ self.session.openWithCallback(
+ self.dirnameSelected,
+ MovieLocationBox,
+ _("Initial location in new timers"),
+ self.timer_dirname.value
+ )
+ elif currentry == self.instantrec_entry:
+ self.entrydirname = self.instantrec_dirname
+ self.session.openWithCallback(
+ self.dirnameSelected,
+ MovieLocationBox,
+ _("Location for instant recordings"),
+ self.instantrec_dirname.value
+ )
+ elif currentry == self.timeshift_entry:
+ self.entrydirname = self.timeshift_dirname
+ config.usage.timeshift_path.value = self.timeshift_dirname.value
+ self.session.openWithCallback(
+ self.dirnameSelected,
+ TimeshiftLocationBox
+ )
+
+ def dirnameSelected(self, res):
+ if res is not None:
+ self.entrydirname.value = res
+ if config.movielist.videodirs.value != self.lastvideodirs:
+ styles_keys = [x[0] for x in self.styles]
+ tmp = config.movielist.videodirs.value
+ default = self.default_dirname.value
+ if default not in tmp:
+ tmp = tmp[:]
+ tmp.append(default)
+ self.default_dirname.setChoices(tmp, default=default)
+ tmp = config.movielist.videodirs.value
+ default = self.timer_dirname.value
+ if default not in tmp and default not in styles_keys:
+ tmp = tmp[:]
+ tmp.append(default)
+ self.timer_dirname.setChoices(self.styles+tmp, default=default)
+ tmp = config.movielist.videodirs.value
+ default = self.instantrec_dirname.value
+ if default not in tmp and default not in styles_keys:
+ tmp = tmp[:]
+ tmp.append(default)
+ self.instantrec_dirname.setChoices(self.styles+tmp, default=default)
+ self.entrydirname.value = res
+ if config.usage.allowed_timeshift_paths.value != self.lasttimeshiftdirs:
+ tmp = config.usage.allowed_timeshift_paths.value
+ default = self.instantrec_dirname.value
+ if default not in tmp:
+ tmp = tmp[:]
+ tmp.append(default)
+ self.timeshift_dirname.setChoices(tmp, default=default)
+ self.entrydirname.value = res
+ if self.entrydirname.last_value != res:
+ self.checkReadWriteDir(self.entrydirname)
+
+ def save(self):
+ currentry = self["config"].getCurrent()
+ if self.checkReadWriteDir(currentry[1]):
+ config.usage.default_path.value = self.default_dirname.value
+ config.usage.timer_path.value = self.timer_dirname.value
+ config.usage.instantrec_path.value = self.instantrec_dirname.value
+ config.usage.timeshift_path.value = self.timeshift_dirname.value
+ config.usage.default_path.save()
+ config.usage.timer_path.save()
+ config.usage.instantrec_path.save()
+ config.usage.timeshift_path.save()
+ self.close()
+
+ def cancel(self):
+ self.close()
+
from Components.MenuList import MenuList
from Components.TimerList import TimerList
from Components.TimerSanityCheck import TimerSanityCheck
+from Components.UsageConfig import preferredTimerPath
from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
from Screen import Screen
from Screens.ChoiceBox import ChoiceBox
else:
data = parseEvent(event, description = False)
- self.addTimer(RecordTimerEntry(serviceref, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *data))
+ self.addTimer(RecordTimerEntry(serviceref, checkOldTimers = True, dirname = preferredTimerPath(), *data))
def addTimer(self, timer):
self.session.openWithCallback(self.finishedAdd, TimerEntry, timer)
from Components.Button import Button
from Components.Label import Label
from Components.Pixmap import Pixmap
+from Components.UsageConfig import defaultMoviePath
from Screens.MovieSelection import getPreferredTagEditor
from Screens.LocationBox import MovieLocationBox
from Screens.ChoiceBox import ChoiceBox
from RecordTimer import AFTEREVENT
-from Tools.Directories import resolveFilename, SCOPE_HDD
from enigma import eEPGCache
from time import localtime, mktime, time, strftime
from datetime import datetime
self.timerentry_starttime = ConfigClock(default = self.timer.begin)
self.timerentry_endtime = ConfigClock(default = self.timer.end)
- default = self.timer.dirname or resolveFilename(SCOPE_HDD)
+ default = self.timer.dirname or defaultMoviePath()
tmp = config.movielist.videodirs.value
if default not in tmp:
tmp.append(default)
self.timer.service_ref = self.timerentry_service_ref
self.timer.tags = self.timerentry_tags
- self.timer.dirname = self.timerentry_dirname.value
- config.movielist.last_timer_videodir.value = self.timer.dirname
- config.movielist.last_timer_videodir.save()
+ if self.timer.dirname or self.timerentry_dirname.value != defaultMoviePath():
+ self.timer.dirname = self.timerentry_dirname.value
+ config.movielist.last_timer_videodir.value = self.timer.dirname
+ config.movielist.last_timer_videodir.save()
if self.timerentry_type.value == "once":
self.timer.begin, self.timer.end = self.getBeginEnd()
/* note: this requires gstreamer 0.10.x and a big list of plugins. */
/* it's currently hardcoded to use a big-endian alsasink as sink. */
+#include <lib/base/ebase.h>
#include <lib/base/eerror.h>
+#include <lib/base/init_num.h>
+#include <lib/base/init.h>
+#include <lib/base/nconfig.h>
#include <lib/base/object.h>
-#include <lib/base/ebase.h>
-#include <string>
+#include <lib/dvb/decoder.h>
+#include <lib/components/file_eraser.h>
+#include <lib/gui/esubtitle.h>
#include <lib/service/servicemp3.h>
#include <lib/service/service.h>
-#include <lib/components/file_eraser.h>
-#include <lib/base/init_num.h>
-#include <lib/base/init.h>
+
+#include <string>
+
#include <gst/gst.h>
#include <gst/pbutils/missing-plugins.h>
#include <sys/stat.h>
-/* for subtitles */
-#include <lib/gui/esubtitle.h>
// eServiceFactoryMP3
extensions.push_back("mp4");
extensions.push_back("mov");
extensions.push_back("m4a");
+ extensions.push_back("m2ts");
sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
}
}
// eServiceMP3
+int eServiceMP3::ac3_delay,
+ eServiceMP3::pcm_delay;
eServiceMP3::eServiceMP3(eServiceReference ref)
:m_ref(ref), m_pump(eApp, 1)
return 0;
}
-
int eServiceMP3::getInfo(int w)
{
const gchar *tag = 0;
return 0;
}
+RESULT eServiceMP3::audioDelay(ePtr<iAudioDelay> &ptr)
+{
+ ptr = this;
+ return 0;
+}
+
int eServiceMP3::getNumberOfTracks()
{
return m_audioStreams.size();
g_object_set (G_OBJECT (sink), "emit-signals", TRUE, NULL);
gst_object_unref(sink);
}
+ setAC3Delay(ac3_delay);
+ setPCMDelay(pcm_delay);
} break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
{
return 0;
}
+int eServiceMP3::getAC3Delay()
+{
+ return ac3_delay;
+}
+
+int eServiceMP3::getPCMDelay()
+{
+ return pcm_delay;
+}
+
+void eServiceMP3::setAC3Delay(int delay)
+{
+ if (!m_gst_playbin || m_state != stRunning)
+ return;
+ else
+ {
+ GstElement *sink;
+ std::string config_delay;
+ int config_delay_int = delay;
+ if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
+ config_delay_int += atoi(config_delay.c_str());
+
+ g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
+
+ if (!sink)
+ return;
+ else {
+ gchar *name = gst_element_get_name(sink);
+
+ if (strstr(name, "dvbaudiosink"))
+ eTSMPEGDecoder::setHwAC3Delay(config_delay_int);
+ g_free(name);
+ gst_object_unref(sink);
+ }
+ }
+}
+
+void eServiceMP3::setPCMDelay(int delay)
+{
+ if (!m_gst_playbin || m_state != stRunning)
+ return;
+ else
+ {
+ GstElement *sink;
+ std::string config_delay;
+ int config_delay_int = delay;
+ if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
+ config_delay_int += atoi(config_delay.c_str());
+
+ g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
+
+ if (!sink)
+ return;
+ else {
+ gchar *name = gst_element_get_name(sink);
+
+ if (strstr(name, "dvbaudiosink"))
+ eTSMPEGDecoder::setHwPCMDelay(config_delay_int);
+ else {
+ // this is realy untested..and not used yet
+ gint64 offset = config_delay_int;
+ offset *= 1000000; // milli to nano
+ g_object_set (G_OBJECT (m_gst_playbin), "ts-offset", offset, NULL);
+ }
+ g_free(name);
+ gst_object_unref(sink);
+ }
+ }
+}
#else
#warning gstreamer not available, not building media player
typedef enum { stPlainText, stSSA, stSRT } subtype_t;
typedef enum { ctNone, ctMPEGTS, ctMPEGPS, ctMKV, ctAVI, ctMP4, ctVCD, ctCDA } containertype_t;
-class eServiceMP3: public iPlayableService, public iPauseableService,
- public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection, public iSubtitleOutput, public iStreamedService, public Object
+class eServiceMP3: public iPlayableService, public iPauseableService,
+ public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection,
+ public iSubtitleOutput, public iStreamedService, public iAudioDelay, public Object
{
DECLARE_REF(eServiceMP3);
public:
RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr);
RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr);
RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
+ RESULT audioDelay(ePtr<iAudioDelay> &ptr);
// not implemented (yet)
RESULT frontendInfo(ePtr<iFrontendInformation> &ptr) { ptr = 0; return -1; }
RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
- RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
+
RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
RESULT keys(ePtr<iServiceKeys> &ptr) { ptr = 0; return -1; }
RESULT stream(ePtr<iStreamableService> &ptr) { ptr = 0; return -1; }
PyObject *getBufferCharge();
int setBufferSize(int size);
+ // iAudioDelay
+ int getAC3Delay();
+ int getPCMDelay();
+ void setAC3Delay(int);
+ void setPCMDelay(int);
+
struct audioStream
{
GstPad* pad;
}
};
private:
+ static int pcm_delay;
+ static int ac3_delay;
int m_currentAudioStream;
int m_currentSubtitleStream;
int selectAudioStream(int i);