def createVideoJob(self, sourceMediaFile=None):
        """
        Creates a job to convert a video file to my own storage requirements
        @param sourceMediaFile Source MediaFile object
        @return Job instance to convert the video
        """
        sourceVideoMediaStreams = sourceMediaFile.getVideoStreams()
        sourceAudioMediaStreams = sourceMediaFile.getAudioStreams()
        masterJob = None
        hanbrakeSourceMediaFile = copy.deepcopy(sourceMediaFile)
        hanbrakeDestinationMediaFile = MediaFile()
        ffmpegSourceMediaFile = MediaFile()
        ffmpegDestinationMediaFile = MediaFile()
        destinationHandbrakeVideoStreams = list()
        destinationHandbrakeAudioStreams = list()
        destinationHandbrakeVideoStream = None
        destinationHandbrakeAudioStream = None

        destinationFFMPEGVideoStreams = list()
        destinationFFMPEGAudioStreams = list()
        destinationFFMPEGVideoStream = None
        destinationFFMPEGAudioStream = None

        # Source video attributes
        sVWidth = None
        sVHeight = None
        sVCodecName = None
        sVCodecTag = None
        sVFramerateMin = None
        # Source audio attributes
        sACodecName = None
        sACodecTag = None
        sABitPerSample = None

        # Handbrake Destination video attributes
        dVHandbrakeCodecName = None
        dVHandbrakeStreamIndex = None
        dVHandbrakeWidth = None
        dVHandbrakeHeight = None
        dVHandbrakeQuality = None
        # Handbrake  Destination audio attributes
        dAHandbrakeStreamIndex = None
        dAHandbrakeSampleRate = None
        dAHandbrakeCodecName = None

        # FFMPEG Destination video attributes
        dVFFMPEGCodecName = None
        # FFMPEG  Destination audio attributes
        dAFFMPEGCodecName = None

        countSourceVideoStreams = len(sourceVideoMediaStreams)
        if countSourceVideoStreams == 1:
            vmsKey = sourceVideoMediaStreams.keys()[0]
            vms = sourceVideoMediaStreams[vmsKey]

            sVWidth = vms.getWidth()
            sVHeight = vms.getHeight()
            sVCodecName = vms.getCodecName()
            sVCodecTag = vms.getCodecTag()
            sVFramerateMin = vms.getFramerateMin()
            sACodecName = None
            sACodecTag = None
            sABitPerSample = None
            dVHandbrakeWidth = sVWidth
            dVHandbrakeHeight = sVHeight

            loggerCameraSourceType = "Not identified"
            skippedJobCreation = True
            skippedReason = ""

            countSourceAudioStreams = len(sourceAudioMediaStreams)
            if countSourceVideoStreams == 1:
                amsKey = sourceAudioMediaStreams.keys()[0]
                ams = sourceAudioMediaStreams[amsKey]
                sACodecName = ams.getCodecName()
                sACodecTag = ams.getCodecTag()
                sABitPerSample = ams.getBitPerSample()
                dAHandbrakeStreamIndex = "1"
                dAHandbrakeSampleRate = ams.getSampleRate()
            else:
                logger.warn("NOTE:" +
                            sourceMediaFile.getFileName() +
                            ": " +
                            str(countSourceVideoStreams) +
                            " audio stream found.")

            # Select appropriate destination media file convertion settings
            # Nikon D3100
            if(sVWidth >= 1280 and sVHeight >= 720 and
                sVCodecName == "h264" and sVCodecTag == "0x31637661" and
                sACodecName == "pcm_s16le" and sACodecTag == "0x74776f73" and
                sABitPerSample == "16"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                dVHandbrakeWidth = 1280
                dVHandbrakeHeight = 720
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Nikon D3100"
                skippedJobCreation = False

            # GoPro Silver 3+ 
            elif(sVCodecName == "h264" and sVCodecTag == "0x31637661" and
                sACodecName == "aac" and sACodecTag == "0x6134706d"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "23"

		eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC

                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "GoPro 3+ Silver"
                skippedJobCreation = False

 
            # Canon Nexus 700
            elif(sVWidth == 320 and sVHeight == 240 and
                sVCodecName == "mjpeg" and sVCodecTag == "0x47504a4d" and
                sACodecName == "pcm_u8" and sACodecTag == "0x0001" and
                sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Canon Nexus 700"
                skippedJobCreation = False

            # iPhone 3GS (NOT MBP 2007 iSight)
            elif(((sVWidth == 640 and sVHeight == 480) or (sVWidth == 480 and sVHeight == 360)) and
                 sVCodecName == "h264" and sVCodecTag == "0x31637661" and
                 sACodecName == "aac" and sACodecTag == "0x6134706d" and
                 sABitPerSample == "0"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "30"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                # quality=25 best quality=35 worst
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "iPhone 3GS"
                skippedJobCreation = False

            # MBP 2010 iSight
            elif(sVWidth == 320 and sVHeight == 240 and
                 sVCodecName == "mjpeg" and sVCodecTag == "" and
                 sACodecName == "pcm_u8" and sACodecTag == "" and
                 sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Macbook Pro iSight 2010"
                skippedJobCreation = False

            # Unknown
            elif(sVWidth == 640 and sVHeight == 480 and
                 sVCodecName == "mjpeg" and sVCodecTag == "" and
                 sACodecName == "pcm_mulaw" and sACodecTag == "" and
                 sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "25"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Unknown0"
                skippedJobCreation = False

            # Panasonic DMC FX-36
            elif(sVWidth == 640 and sVHeight == 480 and
                 sVCodecName == "mjpeg" and sVCodecTag == "0x6765706a" and
                 sACodecName == "pcm_u8" and sACodecTag == "0x20776172" and
                 sABitPerSample == "8"):
                evfH264 = HandbrakeCLGenerator.ENCODER_VIDEO_FORMAT_H264
                dVHandbrakeCodecName = evfH264
                dVHandbrakeStreamIndex = "0"
                dVHandbrakeQuality = "27"
                eafFAAC = HandbrakeCLGenerator.ENCODER_AUDIO_FORMAT_FAAC
                dAHandbrakeCodecName = eafFAAC
                # quality=25 best quality=35 worst
                cfMP4 = HandbrakeCLGenerator.CONTAINER_FORMAT_MP4
                hanbrakeDestinationMediaFile.setContainerType(cfMP4)

                dVFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_VIDEO_FORMAT_COPY
                dAFFMPEGCodecName = FFMPEGCLGenerator.ENCODER_AUDIO_FORMAT_COPY

                loggerCameraSourceType = "Panasonic DMC FX-36"
                skippedJobCreation = False
            # Unknown 1
            elif(sVCodecName == None and sVCodecTag == None and
                 sACodecName == "aac" and sACodecTag == "0x6134706d" and
                 sABitPerSample == "0"):
                # No need to re-encode
                skippedJobCreation = True
                skippedReason = "No need to re-encode"
            else:
                skippedJobCreation = True
                skippedReason = ("No suitable converter configuration found. "
                                + "Missing a convertion case ? "
                                + "New video file ?" )

            if not skippedJobCreation:
                try:
                    masterJob = OnSuccessOnlyConverterJob()
                    # Convert with HandBrake as Job #1
                    hanbrakeSourceMediaFile.setFileName(util.escapePathForOSIndependentShell(hanbrakeSourceMediaFile.getFileName()))
                    destinationHandbrakeVideoStream = VideoStream(codecName=dVHandbrakeCodecName,
                                                                  streamIndex=dVHandbrakeStreamIndex,
                                                                  framerateMin=sVFramerateMin,
                                                                  width=dVHandbrakeWidth,
                                                                  height=dVHandbrakeHeight,
                                                                  quality=dVHandbrakeQuality)
                    destinationHandbrakeAudioStream = AudioStream(streamIndex=dAHandbrakeStreamIndex,
                                                                  sampleRate=dAHandbrakeSampleRate,
                                                                  codecName=dAHandbrakeCodecName)
                    destinationHandbrakeVideoStreams.append(destinationHandbrakeVideoStream)
                    destinationHandbrakeAudioStreams.append(destinationHandbrakeAudioStream)
                    hanbrakeDestinationMediaFile.setVideoStreams(destinationHandbrakeVideoStreams)
                    hanbrakeDestinationMediaFile.setAudioStreams(destinationHandbrakeAudioStreams)
                    handbrakeDestinationFileName = sourceMediaFile.getFileName() + ".tmp." + str(hanbrakeDestinationMediaFile.getContainerType())
                    hanbrakeDestinationMediaFile.setFileName(util.escapePathForOSIndependentShell(handbrakeDestinationFileName))
                    handbrakeCLIBuilder = HandbrakeCLGenerator.createFrom(sourceMediaFile=hanbrakeSourceMediaFile, destinationMediaFile=hanbrakeDestinationMediaFile)
                    handbrakeCLIBuilder.addLooseAnamorphic()
                    handbrakeCLIBuilder.addVerbosity()
                    handbrakeCLIRunner = CLRunner(shell=True)

                    masterJob.addJob(ConverterJob(clibuilder=handbrakeCLIBuilder, clirunner=handbrakeCLIRunner))
                    loggerJobCreationRuntime.info("Handbrake cl:" + str(handbrakeCLIBuilder.tocl()))

                    # Convert with FFMpeg as Job #2
                    destinationFFMPEGVideoStream = VideoStream(codecName=dVFFMPEGCodecName)
                    destinationFFMPEGAudioStream = AudioStream(codecName=dAFFMPEGCodecName)

                    ffmpegSourceMediaFile.setFileName(hanbrakeDestinationMediaFile.getFileName())
                    ffmpegDestinationMediaFile.setFileName(util.escapePathForOSIndependentShell(sourceMediaFile.getFileName()))
                    destinationFFMPEGVideoStreams.append(destinationFFMPEGVideoStream)
                    destinationFFMPEGAudioStreams.append(destinationFFMPEGAudioStream)
                    ffmpegDestinationMediaFile.setVideoStreams(destinationFFMPEGVideoStreams)
                    ffmpegDestinationMediaFile.setAudioStreams(destinationFFMPEGAudioStreams)
                    ffmpegCLIBuilder = FFMPEGCLGenerator.createFrom(sourceMediaFile=ffmpegSourceMediaFile, destinationMediaFile=ffmpegDestinationMediaFile)
                    ffmpegCLIBuilder.addOverwriteOutputFileWithoutAsking()
                    ffmpegCLIRunner = CLRunner(shell=True)
                    loggerJobCreationRuntime.info("ffmpeg cl:" + str(ffmpegCLIBuilder.tocl()))

                    masterJob.addJob(ConverterJob(clibuilder=ffmpegCLIBuilder, clirunner=ffmpegCLIRunner))
                    # Delete temporary file as Job #3
                    masterJob.addJob(DeleteFileJob(filename=handbrakeDestinationFileName))
                    loggerJobCreationRuntime.info("Will delete file:" + str(handbrakeDestinationFileName))
                    loggerJobCreationSuccess.info("JOB_CREATION_SUCCESS:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType)
                except BaseException:
                    loggerJobCreationFailed.exception("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType + "Exception :")
            else:
                loggerJobCreationSkipped.info("JOB_CREATION_SKIPPED:" +
                                              sourceMediaFile.getFileName() +
                                              ": Type:" + loggerCameraSourceType +
                                              " Reason: " + skippedReason)
        else:
            loggerJobCreationFailed.error("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Reason: 1 video stream expected. " + str(countSourceVideoStreams) + " found.")

        if not masterJob:
            masterJob = Job()  # Created only if proper convert job not created
        return masterJob
    def createImageJob(self, sourceMediaFile=None):
        """
        Creates a job to convert image file to my own storage requirements
        @param sourceMediaFile Source MediaFile object
        @return Job instance to convert the image
        """
        sourceImageStreams = sourceMediaFile.getImageStreams()
        masterJob = None
        backupDestinationMediaFile = MediaFile()
        convertDestinationMediaFile = MediaFile()
        destinationBakupImageStreams = list()
        destinationConvertImageStreams = list()

        # Source video attributes
        sIWidth = None
        sIHeight = None
        sIDPIX = None
        sIDPIY = None
        sIQuality = None

        # Handbrake Destination video attributes
        dIWidth = None
        dIHeight = None
        dIDPIX = None
        dIDPIY = None
        dIQuality = None

        countSourceImageStreams = len(sourceImageStreams)
        if countSourceImageStreams == 1:
            imsKey = sourceImageStreams.keys()[0]
            ims = sourceImageStreams[imsKey]

            sIWidth = ims.getWidth()
            sIHeight = ims.getHeight()
            sIDPIX = ims.getDensityX()[0]
            sIDPIY = ims.getDensityY()[0]
            sIQuality = ims.getQuality()
            loggerCameraSourceType = "Not identified"
            skippedJobCreation = True
            skippedReason = ""

            sIQuotientHeightWidth = float(float(sIHeight)/float(sIWidth))

            # Select appropriate destination media file convertion settings
            # Unknown1
            if(sIDPIX == 300 and sIDPIY == 300 and
               sIWidth >= 3508 and sIHeight >= 2480):
                if sIQuotientHeightWidth >= 1.0:
                    sIHeight=3508
                else:
                    dIWidth=2480
                dIQuality=95
                loggerCameraSourceType = "Unknown1"
                skippedJobCreation = False
            # GoPro 3+ Silver - 10MP Wide Mode
            elif(sIDPIX == 72 and sIDPIY == 72 and
               sIWidth == 3680 and sIHeight == 2760):
                dIQuality=92
                loggerCameraSourceType = "GoPro 3+ Silver - 10MP Wide Mode"
                skippedJobCreation = False
            # Unknown2
            elif((sIWidth <= 2480 and sIHeight <= 3508) or
                (sIDPIX <=300 and sIDPIY <=300)):
                # No need to re-encode
                skippedJobCreation = True
                skippedReason = "No need to re-encode"
            else:
                skippedJobCreation = True
                skippedReason = "No suitable converter configuration found. Missing a convertion case ? New image file ?"

            if not skippedJobCreation:
                try:
                    masterJob = OnSuccessOnlyConverterJob()
                    # Backup file as Job #1
                    sourceBackupFileName = sourceMediaFile.getFileName()
                    destinationBackupFileName = str(sourceBackupFileName) + ".backup"
                    destinationBackupMediaFile = MediaFile()
                    destinationBackupMediaFile.setFileName(destinationBackupFileName)
                    copyFileJob = CopyFileJob(sourceFileName=sourceMediaFile.getFileName(), destinationFileName=destinationBackupMediaFile.getFileName())
                    masterJob.addJob(copyFileJob)
                    loggerJobCreationRuntime.info("Will backup file: " + str(sourceBackupFileName) + " to " + str(destinationBackupFileName))

                    # Convert with ImageMagick's mogrity tool as Job #2
                    convertSourceMediaFile = MediaFile()
                    convertSourceMediaFile.setFileName(util.escapePathForOSIndependentShell(destinationBackupFileName))
                    convertDestinationFileName = sourceMediaFile.getFileName()
                    convertDestinationMediaFile.setFileName(util.escapePathForOSIndependentShell(convertDestinationFileName))
                    destinationConvertImageStream = ImageStream(filename=convertDestinationFileName, width=dIWidth, height=sIHeight, quality=dIQuality, densityX=dIDPIX, densityY=dIDPIY)
                    destinationConvertImageStreams.append(destinationConvertImageStream)
                    convertDestinationMediaFile.setImageStreams(destinationConvertImageStreams)
                    convertCLIBuilder = ConvertCLGenerator.createResizeJobFrom(sourceMediaFile=convertSourceMediaFile, destinationMediaFile=convertDestinationMediaFile)
                    convertCLIRunner = CLRunner(shell=True)

                    masterJob.addJob(ConverterJob(clibuilder=convertCLIBuilder, clirunner=convertCLIRunner))
                    loggerJobCreationRuntime.info("convert cl:" + str(convertCLIBuilder.tocl()))

                    # Delete backup file as Job #3
                    masterJob.addJob(DeleteFileJob(filename=destinationBackupMediaFile.getFileName()))
                    loggerJobCreationRuntime.info("Will delete file:" + str(destinationBackupMediaFile.getFileName()))
                    loggerJobCreationSuccess.info("JOB_CREATION_SUCCESS:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType)
                except BaseException:
                    loggerJobCreationFailed.exception("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Type:" + loggerCameraSourceType + "Exception :")
            else:
                loggerJobCreationSkipped.info("JOB_CREATION_SKIPPED:" +
                                              sourceMediaFile.getFileName() +
                                              ": Type:" + loggerCameraSourceType
                                              + " Reason: " +skippedReason)			
        else:
            loggerJobCreationFailed.error("JOB_CREATION_FAILED:" + sourceMediaFile.getFileName() + ": Reason: 1 video stream expected. " + str(countSourceVideoStreams) + " found.")

        if not masterJob:
            masterJob = Job()  # Created only if proper convert job not created 
        return masterJob