Ejemplo n.º 1
0
    def setFile(self,filePath):
        if self.player is not None:
            self.player.close()
            self.videoCuts=[]
        try:
            self.streamData = FFStreamProbe(filePath)
            self.currentPath = OSTools().getPathWithoutExtension(filePath); 
        except: 
            self.streamData = None  
            self.currentPath = OSTools().getHomeDirectory()    
        try:            
            self.player = VideoPlayer(filePath,self.streamData) 
            self._initSliderThread()
            self.player.validate()
            
            self.__initSliderTicks()
            self.gui.enableControls(True)
            #set ratio
            self.gui.getVideoWidget().setVideoRatio(self.streamData.getAspectRatio())

            self.gui.updateWindowTitle(OSTools().getFileNameOnly(filePath))
            self._asyncInitVideoViews()
           
        except:
            self.gui.updateWindowTitle(OSTools().getFileNameOnly(filePath))
            self._gotoFrame(0)
            self._showCurrentFrameInfo(0)
            if not OSTools().fileExists(filePath):
                msg = "File not found"
            else:
                msg = "Invalid file format!"
            
            self.gui.showWarning(msg)
            self.gui.enableControls(False)
Ejemplo n.º 2
0
def testFrameProbe():
    # m=FFStreamProbe("/home/matze/Videos/Handy-M4-Test/MOV_0296.MP4")
    # m=FFStreamProbe("/media/matze/Datastore/Videos/VCR/KiKA/11_13_19_25-pur+.m2t")
    # m=FFStreamProbe("/media/matze/Datastore/Videos/VCR/3sat_HD/11_24_07_00-nano.m2t")
    # m=FFStreamProbe("/media/matze/Datastore/Videos/6.Folge Craftattack.mp4")
    # m=FFStreamProbe("/home/matze/Videos/20051210-w50s.flv")
    # m=FFStreamProbe("/home/matze/Videos/recme/sample.3gp")
    # m=FFStreamProbe("/home/matze/Videos/handbrake.txt")
    # m=FFStreamProbe("/home/matze/Videos/CT.m2t")
    m = FFStreamProbe("/media/disk1/makemkv/title_t00.mkv")

    m.printCodecInfo()
    m.formatInfo._print()
    print ("getAspect2 ", m.getAspectRatio())
    
    container = m.formatInfo
    print ("-------- container: -------------")
    print ("formats:", container.formatNames())
    print ("bit-rate kb:", container.getBitRate())
    print ("duration:", container.getDuration())
    print ("size kb:", container.getSizeKB())
    print ("is TS:", m.isTransportStream())
    
    print ("-------- langMApping: -------------")
    langmap = m.getLanguageMapping()
    for key, index in langmap.items():
        print("lang:%s @ %d" % (key, index))
    
    print ("-------- all streams -------------")  
    for s in m.streams:
        print ("##########################")
        print ("Index:", s.getStreamIndex())
        print ("getCodec:", s.getCodec())
        print ("getLanguage:", s.getLanguage())
        print ("getCodecTimeBase: ", s.getCodecTimeBase())
        print ("getTimeBase: ", s.getTimeBase())
        print ("getAspect ", s.getAspectRatio())
        print ("getFrameRate: ", s.getFrameRate())
        print ("getDuration: ", s.duration())
        print ("getWidth: ", s.getWidth())
        print ("getHeight: ", s.getHeight())
        print ("isAudio: ", s.isAudio())
        print ("isVideo: ", s.isVideo())
Ejemplo n.º 3
0
class VideoControl(QObject):
    def __init__(self,mainFrame):
        #super(VideoControl, self).__init__()
        QObject.__init__(self)
        self.player = None
        self.gui = mainFrame
        self._frameSet=False
        self._initTimer()
        self.videoCuts=[]
        self.currentPath = OSTools().getHomeDirectory()#//TODO get a Video dir
        self.streamData = None
        self._vPlayer = None
        self.exactcut = False

    def _initTimer(self):
        self._timer = QTimer(self.gui)
        self._timer.timeout.connect(self._displayAutoFrame)

    
    def getTargetFile(self):
        if self.streamData is not None:
            return self.currentPath+"."+self.streamData.getTargetExtension()

        return self.currentPath
        
    #-- Menu handling ---    
    def setFile(self,filePath):
        if self.player is not None:
            self.player.close()
            self.videoCuts=[]
        try:
            self.streamData = FFStreamProbe(filePath)
            self.currentPath = OSTools().getPathWithoutExtension(filePath); 
        except: 
            self.streamData = None  
            self.currentPath = OSTools().getHomeDirectory()    
        try:            
            self.player = VideoPlayer(filePath,self.streamData) 
            self._initSliderThread()
            self.player.validate()
            
            self.__initSliderTicks()
            self.gui.enableControls(True)
            #set ratio
            self.gui.getVideoWidget().setVideoRatio(self.streamData.getAspectRatio())

            self.gui.updateWindowTitle(OSTools().getFileNameOnly(filePath))
            self._asyncInitVideoViews()
           
        except:
            self.gui.updateWindowTitle(OSTools().getFileNameOnly(filePath))
            self._gotoFrame(0)
            self._showCurrentFrameInfo(0)
            if not OSTools().fileExists(filePath):
                msg = "File not found"
            else:
                msg = "Invalid file format!"
            
            self.gui.showWarning(msg)
            self.gui.enableControls(False)
    
    def setExactCut(self,reencode): 
        self.exactcut = Qt.Checked==reencode   

    def addStartMarker(self):
        self._createVideoCutEntry(VideoCutEntry.MODE_START)
        self.gui._widgets.statusMessenger.say("Marker created")

    def addStopMarker(self):
        self._createVideoCutEntry(VideoCutEntry.MODE_STOP)

    def _createVideoCutEntry(self,mode,updateXML=True):
        self.sliderThread.wait()
        frame = self.player.getCurrentFrame()
        framePos = self.player.getCurrentFrameNumber()
        timePos = self.player.getCurrentFrameTime()
        cutEntry = VideoCutEntry(framePos,timePos,mode)
        self._addVideoCut(frame, cutEntry,updateXML)
        

    def _addVideoCut(self,frame,cutEntry,updateXML):
        rowIndex=len(self.videoCuts)
        for idx, videoEntry in enumerate(self.videoCuts):
            frameNbr = videoEntry.frameNumber
            testNbr = cutEntry.frameNumber
            if testNbr < frameNbr:
                rowIndex=idx
                break
        
        self.videoCuts.insert(rowIndex,cutEntry)
        self.gui.addCutMark(frame,cutEntry,rowIndex)
        if updateXML:
            XMLAccessor(self.currentPath).writeXML(self.videoCuts)

    def _asyncInitVideoViews(self):
        #QTimer.singleShot(10,self._gotoFrame)
        QTimer.singleShot(10,self._grabNextFrame)
        QTimer.singleShot(150, self.restoreVideoCuts)

    def restoreVideoCuts(self):
        self.sliderThread.wait() #sync with the worker
        
        cutList=XMLAccessor(self.currentPath).readXML()  
        for cut in cutList:
            fbnr = cut.frameNumber
            self.player.setFrameAt(fbnr)
            mode = VideoCutEntry.MODE_STOP
            if cut.isStartMode():
                mode = VideoCutEntry.MODE_START
            self._createVideoCutEntry(mode,False)


        self.player.setFrameAt(0)          
    
    #remove/clear all cuts but leave the file untouched
    def clearVideoCutEntries(self):
        self.videoCuts=[]

    #clear all cuts and its persistence
    def purgeVideoCuts(self):
        self.clearVideoCutEntries()
        XMLAccessor(self.currentPath).clear()        
    
    def removeVideoCutIndex(self,index):
        cut = self.videoCuts[index]
        self.videoCuts.remove(cut)
        XMLAccessor(self.currentPath).writeXML(self.videoCuts)
    
    def gotoCutIndex(self,index):
        cut = self.videoCuts[index]
        self._gotoFrame(cut.frameNumber)
    

    def saveVideo(self,path):
        spanns=[]
        block = None
        for cutEntry in self.videoCuts:
            
            if cutEntry.isStartMode():
                if block:
                    print "Start invalid:", cutEntry.getTimeString()
                else:
                    block=[]
                    block.append(cutEntry)
                    print "Start ok:", cutEntry.getTimeString()
            else:
                if block:
                    print "Stop:", cutEntry.getTimeString()
                    block.append(cutEntry)
                    spanns.append(block)
                    block=None
                else:
                    print "Stop ignored:", cutEntry.getTimeString()
    
        for cutmarks in spanns:
            print cutmarks[0].getTimeString(),"-",cutmarks[1].getTimeString()
        
        src = self.player._file
        #need that without extension!
        self.cutAsync(src,path,spanns)
    
    #-- Menu handling end ---

    def cutAsync(self,srcPath,targetPath,spanns):
        worker = LongRunningOperation(self.__makeCuts,srcPath, targetPath, spanns)
        self.connect(worker,worker.signalDone,self.gui.stopProgress)
        #start the worker thread. 
        worker.startOperation()  
 

    def __makeCuts(self,srcPath,targetPath,spanns):
        config = CuttingConfig(srcPath,targetPath)
        config.streamData = self.streamData
        config.reencode = self.exactcut
        config.messenger = self.gui._widgets.statusMessenger
        cutter = FFMPEGCutter(config)
        
        cutter.ensureAvailableSpace()
        slices = len(spanns)
        for index, cutmark in enumerate(spanns):
            t1=cutmark[0].timePos
            t2 = cutmark[1].timePos
            hasSucess = cutter.cutPart(t1, t2, index,slices)
            if not hasSucess:
                print"VC-Cut error" #TODO need a signal for error
                return
        cutter.join()    
        
    '''

    '''
    def _initSliderThread(self):
        self.sliderThread = Worker(self.player.getFrameAt)
        self.connect(self.sliderThread,self.sliderThread.signal,self._showFrame)
    
    #we want 1 minute per single step
    def __initSliderTicks(self):
        videoInfo= self.streamData.getVideoStream()
        fps = videoInfo.getFrameRate()
        if self.player.framecount > 0:
            ratio = round(LayoutWindow.SLIDER_RESOLUTION*60*fps/self.player.framecount,1)
            self.gui.setSliderTicks(ratio)
            self.gui.setDialResolution(fps)
            self.gui.setGotoMaximum(self.player.framecount)
        self._frameSet=False 
         
        
    #connected to slider-called whenever position is changed.
    def sliderMoved(self,pos):
        if self.player is None or not self.player.isValid():
            self.gui.syncSliderPos(0)
        if not self._frameSet: 
            frameNumber = round(self.player.framecount/LayoutWindow.SLIDER_RESOLUTION*pos,0)
            self.__dispatchShowFrame(frameNumber)
        self._frameSet=False

    #display Frame with syncing the slider pos. 
    def _gotoFrame(self,frameNumber=0):
        self._frameSet=True
        if self.player.framecount < 1:
            return;
        if frameNumber == 0:
            sliderPos=0
        else:
            sliderPos= int(frameNumber*LayoutWindow.SLIDER_RESOLUTION/self.player.framecount)
        self.gui.syncSliderPos(sliderPos)
        self.__dispatchShowFrame(frameNumber)
    
    def __dispatchShowFrame(self,frameNumber):
        if self._vPlayer is None:
            self.sliderThread.showFrame(frameNumber)
    
    #connected to the dial
    def dialChanged(self,pos):
        if self.player is None or pos == 0:
            self._timer.stop()
            return
        self._dialStep = pos
        #self._dialStep = 1
        ts=(1/self.player.fps)*2500
        #print "dial:",pos, " time:",ts
        self._timer.start(ts)
 
    #called by timer on dial change...    
    def _displayAutoFrame(self):
        if self.player is None or not self.player.isValid():
            return
        self.sliderThread.wait()#No concurrency with worker!
        self._frameSet = True
        frameNumber = max(0,self.player.getCurrentFrameNumber()+self._dialStep);
        sliderPos= int(frameNumber*LayoutWindow.SLIDER_RESOLUTION/self.player.framecount)
        self.gui.syncSliderPos(sliderPos)
        aFrame = self.player.getFrameAt(frameNumber)
        self._showFrame(aFrame)
#        self._gotoFrame(frameNumber)
        self._frameSet = False
        
    #called by worker ...
    def _showFrame(self,aFrame):
        self._videoUI().showFrame(aFrame)
        x = self.player.getCurrentFrameNumber()
        self._showCurrentFrameInfo(x)
        
    def _displayFrame(self,frameNumber):
        self._videoUI().showFrame(self.player.getFrameAt(frameNumber))

    def _videoUI(self):
        return self.gui.getVideoWidget()

    
    def _showCurrentFrameInfo(self,frameNumber):
        timeinfo = self.player.getCurrentFrameTime()
        #basket = "%02d.%03i" %(timeinfo.seconds,timeinfo.microseconds/1000)
        out = "Frame: %s Time: %s max: %s" %(str(frameNumber), str(timeinfo),str(self.player.framecount))
        #TODO: Pass 3 values for 3 widgets....
        self.gui.showInfo(out)

    
    def toggleVideoPlay(self):
        if self.streamData is None:
            return False
        if self._vPlayer is None:
            return self.__playVideo()
        
        return self.__stopVideo()

    #TODO Warning, if it runs, Worker may NOT be used!
    def __playVideo(self):
        self._vPlayer = QTimer(self.gui)
        self._vPlayer.timeout.connect(self._grabNextFrame)
        #50 ms if 25 fps and 25 if 50fps
        fRate=(1/self.player.fps)*1250
        self._vPlayer.start(fRate)
        return True

    def __stopVideo(self):
            self._vPlayer.stop()
            self._vPlayer = None
            self._frameSet = False
            return False

    def _grabNextFrame(self):
        self._frameSet = True
        frame= self.player.grabNextFrame()
        if frame is not None:
            self._videoUI().showFrame(frame)
            frameNumber = self.player.getCurrentFrameNumber()
            sliderPos= int(frameNumber*LayoutWindow.SLIDER_RESOLUTION/self.player.framecount)
            self._showCurrentFrameInfo(frameNumber)
            self.gui.syncSliderPos(sliderPos)
        else:
            self.gui.setVideoPlayerControls(False)
            self.player.framecount = self.player.getCurrentFrameNumber()
            self.__stopVideo()