예제 #1
0
    def merge(self):
        if self.detect is None:
            log.error(
                "Cant detect ffmpeg or avconv. Cant mux files without it.")
            return

        if self.stream.finished is False:
            return
        orig_filename = self.stream.options.output
        log.info("Merge audio and video into %s", orig_filename)
        tempfile = "{0}.temp".format(self.stream.options.output)
        audio_filename = "{0}.m4a".format(
            os.path.splitext(self.stream.options.output)[0])
        arguments = [
            "-c:v", "copy", "-c:a", "copy", "-f", "mp4", "-y", tempfile
        ]
        cmd = [self.detect, "-i", orig_filename, "-i", audio_filename]
        cmd += arguments
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE)
        stdout, stderr = p.communicate()
        if p.returncode != 0:
            stderr = stderr.decode('utf-8', 'replace')
            msg = stderr.strip().split('\n')[-1]
            log.error("Something went wrong: %s", msg)
            return
        log.info("Merging done, removing old files.")
        os.remove(self.stream.options.output)
        os.remove(audio_filename)
        os.rename(tempfile, self.stream.options.output)
예제 #2
0
    def remux(self):
        if self.detect is None:
            log.error(
                "Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        if self.stream.options.output.endswith('.mp4') is False:
            orig_filename = self.stream.options.output
            new_name = "{0}.mp4".format(
                os.path.splitext(self.stream.options.output)[0])

            log.info("Muxing %s into %s", orig_filename, new_name)
            tempfile = "{0}.temp".format(self.stream.options.output)
            name, ext = os.path.splitext(orig_filename)
            arguments = ["-c", "copy", "-copyts", "-f", "mp4"]
            if ext == ".ts":
                arguments += ["-bsf:a", "aac_adtstoasc"]
            arguments += ["-y", tempfile]
            cmd = [self.detect, "-i", orig_filename]
            cmd += arguments
            p = subprocess.Popen(cmd,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 stdin=subprocess.PIPE)
            stdout, stderr = p.communicate()
            if p.returncode != 0:
                stderr = stderr.decode('utf-8', 'replace')
                msg = stderr.strip().split('\n')[-1]
                log.error("Something went wrong: %s", msg)
                return
            log.info("Muxing done, removing the old file.")
            os.remove(self.stream.options.output)
            os.rename(tempfile, new_name)
예제 #3
0
def output(options, filename, extention="mp4", openfd=True):
    if is_py3:
        file_d = io.IOBase
    else:
        file_d = file

    if options.output != "-":
        ext = re.search(r"(\.[a-z0-9]+)$", filename)
        if not ext:
            options.output = "%s.%s" % (options.output, extention)
        log.info("Outfile: %s", options.output)
        if (os.path.isfile(options.output) or \
            findexpisode(os.path.dirname(os.path.realpath(options.output)), options.service, os.path.basename(options.output))) and \
            not options.force:
            log.error("File already exists. Use --force to overwrite")
            return None
        if openfd:
            file_d = open(options.output, "wb")
    else:
        if openfd:
            if is_py3:
                file_d = sys.stdout.buffer
            else:
                file_d = sys.stdout

    return file_d
예제 #4
0
def get_all_episodes(stream, url):
    name = os.path.dirname(formatname(dict(), stream.config))

    if name and os.path.isfile(name):
        log.error("Output must be a directory if used with --all-episodes")
        sys.exit(2)
    elif name and not os.path.exists(name):
        try:
            os.makedirs(name)
        except OSError as e:
            log.error("%s: %s", e.strerror, e.filename)
            return

    episodes = stream.find_all_episodes(stream.config)
    if episodes is None:
        return
    for idx, o in enumerate(episodes):
        if o == url:
            substream = stream
        else:
            substream = service_handler(sites, copy.copy(stream.config), o)

        log.info("Episode %d of %d", idx + 1, len(episodes))
        log.info("Url: %s", o)

        # get_one_media overwrites options.output...
        get_one_media(substream)
예제 #5
0
def get_all_episodes(stream, options, url):
    if options.output and os.path.isfile(options.output):
        log.error("Output must be a directory if used with --all-episodes")
        sys.exit(2)
    elif options.output and not os.path.exists(options.output):
        try:
            os.makedirs(options.output)
        except OSError as e:
            log.error("%s: %s", e.strerror, e.filename)
            return

    episodes = stream.find_all_episodes(options)
    if episodes is None:
        return
    for idx, o in enumerate(episodes):
        if o == url:
            substream = stream
        else:
            substream = service_handler(sites, copy.copy(options), o)

        log.info("Episode %d of %d", idx + 1, len(episodes))
        log.info("Url: %s",o) 

        # get_one_media overwrites options.output...
        get_one_media(substream, copy.copy(options))
예제 #6
0
def output(options, extension="mp4", openfd=True, mode="wb", **kwargs):
    subtitlefiles = ["srt", "smi", "tt","sami", "wrst"]

    ext = re.search(r"(\.\w{2,4})$", options.output)
    if not ext:
        options.output = "%s.%s" % (options.output, extension)
    if options.output_auto and ext:
        options.output = "%s.%s" % (options.output, extension)
    elif extension == "srt" and ext:
        options.output = "%s.srt" % options.output[:options.output.rfind(ext.group(1))]
    if ext and extension == "srt" and ext.group(1).split(".")[-1] in subtitlefiles:
        options.output = "%s.srt" % options.output[:options.output.rfind(ext.group(1))]
    log.info("Outfile: %s", options.output)
    if os.path.isfile(options.output) or \
            findexpisode(os.path.dirname(os.path.realpath(options.output)), options.service, os.path.basename(options.output)):
        if extension in subtitlefiles:
            if not options.force_subtitle:
                log.error("File (%s) already exists. Use --force-subtitle to overwrite" % options.output)
                return None
        else:
            if not options.force:
                log.error("File (%s) already exists. Use --force to overwrite" % options.output)
                return None
    if openfd:
        file_d = open(options.output, mode, **kwargs)
        return file_d
    return True
예제 #7
0
    def merge(self):
        if self.detect is None:
            log.error("Cant detect ffmpeg or avconv. Cant mux files without it.")
            return

        if self.stream.finished is False:
            return
        orig_filename = self.stream.options.output
        log.info("Merge audio and video into %s", orig_filename)
        tempfile = "{0}.temp".format(self.stream.options.output)
        audio_filename = "{0}.m4a".format(os.path.splitext(self.stream.options.output)[0])
        arguments = ["-c:v", "copy", "-c:a", "copy", "-f", "mp4", "-y", tempfile]
        cmd = [self.detect, "-i", orig_filename, "-i", audio_filename]
        cmd += arguments
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        stdout, stderr = p.communicate()
        if p.returncode != 0:
            stderr = stderr.decode('utf-8', 'replace')
            msg = stderr.strip().split('\n')[-1]
            log.error("Something went wrong: %s", msg)
            return
        log.info("Merging done, removing old files.")
        os.remove(self.stream.options.output)
        os.remove(audio_filename)
        os.rename(tempfile, self.stream.options.output)
예제 #8
0
파일: output.py 프로젝트: vikekh/svtplay-dl
def output(options, extension="mp4", openfd=True, mode="wb", **kwargs):
    subtitlefiles = ["srt", "smi", "tt", "sami", "wrst"]

    ext = re.search(r"(\.\w{2,4})$", options.output)
    if not ext:
        options.output = "%s.%s" % (options.output, extension)
    if options.output_auto and ext:
        options.output = "%s.%s" % (options.output, extension)
    elif extension == "srt" and ext:
        options.output = "%s.srt" % options.output[:options.output.rfind(ext.group(1))]
    if ext and extension == "srt" and ext.group(1).split(".")[-1] in subtitlefiles:
        options.output = "%s.srt" % options.output[:options.output.rfind(ext.group(1))]
    log.info("Outfile: %s", options.output)
    if os.path.isfile(options.output) or \
            findexpisode(os.path.dirname(os.path.realpath(options.output)), options.service, os.path.basename(options.output)):
        if extension in subtitlefiles:
            if not options.force_subtitle:
                log.error("File (%s) already exists. Use --force-subtitle to overwrite" % options.output)
                return None
        else:
            if not options.force:
                log.error("File (%s) already exists. Use --force to overwrite" % options.output)
                return None
    if openfd:
        file_d = open(options.output, mode, **kwargs)
        return file_d
    return True
예제 #9
0
 def remux(self):
     if self.detect is None:
         log.error("Cant detect ffmpeg or avconv. Cant mux files without it.")
         return
     if self.stream.finished is False:
         return
     
     if self.stream.options.output.endswith('.mp4') is False:
         orig_filename = self.stream.options.output
         new_name = "{0}.mp4".format(os.path.splitext(self.stream.options.output)[0])
 
         log.info("Muxing %s into %s", orig_filename, new_name)
         tempfile = "{0}.temp".format(self.stream.options.output)
         name, ext = os.path.splitext(orig_filename)
         arguments = ["-c", "copy", "-copyts", "-f", "mp4"]
         if ext == ".ts":
             arguments += ["-bsf:a", "aac_adtstoasc"]
         arguments += ["-y", tempfile]
         cmd = [self.detect, "-i", orig_filename]
         cmd += arguments
         p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
         stdout, stderr = p.communicate()
         if p.returncode != 0:
             stderr = stderr.decode('utf-8', 'replace')
             msg = stderr.strip().split('\n')[-1]
             log.error("Something went wrong: %s", msg)
             return
         log.info("Muxing done, removing the old file.")
         os.remove(self.stream.options.output)
         os.rename(tempfile, new_name)
예제 #10
0
def get_media(url, options):

    stream = service_handler(url)
    if not stream:
        url, stream = Generic().get(url)
    if not stream:
        log.error("That site is not supported. Make a ticket or send a message")
        sys.exit(2)

    if options.all_episodes:
        if options.output and os.path.isfile(options.output):
            log.error("Output must be a directory if used with --all-episodes")
            sys.exit(2)
        elif options.output and not os.path.exists(options.output):
            try:
                os.makedirs(options.output)
            except OSError as e:
                log.error("%s: %s" % (e.strerror,  e.filename))
                return

        episodes = stream.find_all_episodes(options)

        for idx, o in enumerate(episodes):
            if o == url:
                substream = stream
            else:
                substream = service_handler(o)

            log.info("Episode %d of %d", idx + 1, len(episodes))

            # get_one_media overwrites options.output...
            get_one_media(substream, copy.copy(options))
    else:
        get_one_media(stream, options)
예제 #11
0
파일: rtmp.py 프로젝트: drtobbe/svtplay-dl
def download_rtmp(options, url):
    """ Get the stream from RTMP """
    args = []
    if options.live:
        args.append("-v")

    if options.resume:
        args.append("-e")

    extension = re.search("(\.[a-z0-9]+)$", url)
    if options.output != "-":
        if not extension:
            extension = re.search("-y (.+):[-_a-z0-9\/]", options.other)
            if not extension:
                options.output = "%s.flv" % options.output
            else:
                options.output = "%s.%s" % (options.output, extension.group(1))
        else:
            options.output = options.output + extension.group(1)
        log.info("Outfile: %s", options.output)
        args += ["-o", options.output]
    if options.silent or options.output == "-":
        args.append("-q")
    if options.other:
        if sys.version_info < (3, 0):
            args += shlex.split(options.other.encode("utf-8"))
        else:
            args += shlex.split(options.other)
    command = ["rtmpdump", "-r", url] + args
    try:
        subprocess.call(command)
    except OSError as e:
        log.error("Could not execute rtmpdump: " + e.strerror)
예제 #12
0
def output(options, filename, extention="mp4", openfd=True):
    if is_py3:
        file_d = io.IOBase
    else:
        file_d = file

    if options.output != "-":
        ext = re.search(r"(\.[a-z0-9]+)$", filename)
        if not ext:
            options.output = "%s.%s" % (options.output, extention)
        log.info("Outfile: %s", options.output)
        if (os.path.isfile(options.output) or \
            findexpisode(os.path.dirname(os.path.realpath(options.output)), options.service, os.path.basename(options.output))) and \
            not options.force:
            log.error("File already exists. Use --force to overwrite")
            return None
        if openfd:
            file_d = open(options.output, "wb")
    else:
        if openfd:
            if is_py3:
                file_d = sys.stdout.buffer
            else:
                file_d = sys.stdout

    return file_d
예제 #13
0
def output(options, extention="mp4", openfd=True, mode="wb", **kwargs):
    if is_py2:
        file_d = file
    else:
        file_d = io.IOBase

    if options.output != "-":
        ext = re.search(r"(\.\w{2,3})$", options.output)
        if not ext:
            options.output = "%s.%s" % (options.output, extention)
        if options.output_auto and ext:
            options.output = "%s.%s" % (options.output, extention)
        if extention == "srt" and ext:
            options.output = "%s.srt" % options.output[:options.output.rfind(ext.group(1))]
        log.info("Outfile: %s", options.output)
        if os.path.isfile(options.output) or \
                findexpisode(os.path.dirname(os.path.realpath(options.output)), options.service, os.path.basename(options.output)):
            if extention == "srt":
                if not options.force_subtitle:
                    log.error("File (%s) already exists. Use --force-subtitle to overwrite" % options.output)
                    return None
            else:
                if not options.force:
                    log.error("File (%s) already exists. Use --force to overwrite" % options.output)
                    return None
        if openfd:
            file_d = open(options.output, mode, **kwargs)
    else:
        if openfd:
            if is_py2:
                file_d = sys.stdout
            else:
                file_d = sys.stdout.buffer

    return file_d
예제 #14
0
def get_one_media(stream, options):
    if not options.output or os.path.isdir(options.output):
        data = stream.get_urldata()
        match = re.search(r"(?i)<title[^>]*>\s*(.*?)\s*</title>", data, re.S)
        if match:
            options.output_auto = True
            title_tag = decode_html_entities(match.group(1))
            if not options.output:
                options.output = filenamify(title_tag)
            else:
                # output is a directory
                options.output = os.path.join(options.output, filenamify(title_tag))

    if platform.system() == "Windows":
        # ugly hack. replace \ with / or add extra \ because c:\test\kalle.flv will add c:_tab_est\kalle.flv
        if options.output.find("\\") > 0:
            options.output = options.output.replace("\\", "/")

    videos = []
    subs = []
    streams = stream.get(options)
    for i in streams:
        if isinstance(i, VideoRetriever):
            if options.preferred:
                if options.preferred == i.name():
                    videos.append(i)
            else:
                videos.append(i)
        if isinstance(i, subtitle):
            subs.append(i)

    if options.subtitle and options.output != "-":
        if subs:
            subs[0].download(copy.copy(options))
        if options.force_subtitle:
            return

    if len(videos) == 0:
        log.error("Can't find any streams for that url")
    else:
        stream = select_quality(options, videos)
        log.info("Selected to download %s, bitrate: %s",
            stream.name(), stream.bitrate)
        try:
            stream.download()
        except UIException as e:
            if options.verbose:
                raise e
            log.error(e.message)
            sys.exit(2)

        if options.thumbnail and hasattr(stream, "get_thumbnail"):
            if options.output != "-":
                log.info("Getting thumbnail")
                stream.get_thumbnail(options)
            else:
                log.warning("Can not get thumbnail when fetching to stdout")
예제 #15
0
    def download(self):
        if self.options.live and not self.options.force:
            raise LiveHLSException(self.url)

        m3u8 = get_http_data(self.url)
        globaldata, files = parsem3u(m3u8)
        encrypted = False
        key = None
        try:
            keydata = globaldata["KEY"]
            encrypted = True
        except KeyError:
            pass

        if encrypted:
            try:
                from Crypto.Cipher import AES
            except ImportError:
                log.error("You need to install pycrypto to download encrypted HLS streams")
                sys.exit(2)

            match = re.search(r'URI="(https?://.*?)"', keydata)
            key = get_http_data(match.group(1))
            rand = os.urandom(16)
            decryptor = AES.new(key, AES.MODE_CBC, rand)
        if self.options.output != "-":
            extension = re.search(r"(\.[a-z0-9]+)$", self.options.output)
            if not extension:
                self.options.output = "%s.ts" % self.options.output
            log.info("Outfile: %s", self.options.output)
            if os.path.isfile(self.options.output) and not self.options.force:
                log.info("File already exists. use --force to overwrite")
                return
            file_d = open(self.options.output, "wb")
        else:
            file_d = sys.stdout

        n = 0
        eta = ETA(len(files))
        for i in files:
            item = _get_full_url(i[0], self.url)

            if self.options.output != "-":
                eta.increment()
                progressbar(len(files), n, ''.join(['ETA: ', str(eta)]))
                n += 1

            data = get_http_data(item)
            if encrypted:
                data = decryptor.decrypt(data)
            file_d.write(data)

        if self.options.output != "-":
            file_d.close()
            progress_stream.write('\n')
예제 #16
0
def save(options, data):
    filename = re.search(r"(.*)\.[a-z0-9]{2,3}$", options.output)
    if filename:
        options.output = "%s.srt" % filename.group(1)
    else:
        options.output = "%s.srt" % options.output

    log.info("Subtitle: %s", options.output)
    fd = open(options.output, "w")
    fd.write(data)
    fd.close()
예제 #17
0
def get_one_media(stream, options):
    # Make an automagic filename
    if not filename(options, stream):
        return

    videos = []
    subs = []
    streams = stream.get(options)
    for i in streams:
        if isinstance(i, VideoRetriever):
            if options.preferred:
                if options.preferred.lower() == i.name():
                    videos.append(i)
            else:
                videos.append(i)
        if isinstance(i, subtitle):
            subs.append(i)

    if options.subtitle and options.output != "-":
        if subs:
            subs[0].download()
        if options.force_subtitle:
            return

    if len(videos) == 0:
        log.error("Can't find any streams for that url")
    else:
        if options.list_quality:
            list_quality(videos)
            return
        stream = select_quality(options, videos)
        log.info("Selected to download %s, bitrate: %s",
                 stream.name(), stream.bitrate)
        if options.get_url:
            print(stream.url)
            return
        try:
            stream.download()
        except UIException as e:
            if options.verbose:
                raise e
            log.error(e.message)
            sys.exit(2)

        if options.thumbnail and hasattr(stream, "get_thumbnail"):
            if options.output != "-":
                log.info("Getting thumbnail")
                stream.get_thumbnail(options)
            else:
                log.warning("Can not get thumbnail when fetching to stdout")
예제 #18
0
def save(options, data):
    filename = re.search(r"(.*)\.[a-z0-9]{2,3}$", options.output)
    if filename:
        options.output = "%s.srt" % filename.group(1)
    else:
        options.output = "%s.srt" % options.output

    log.info("Subtitle: %s", options.output)
    if os.path.isfile(options.output) and not options.force:
        log.info("File already exists. use --force to overwrite")
        return
    fd = open(options.output, "w")
    fd.write(data)
    fd.close()
예제 #19
0
def save(options, data):
    filename = re.search(r"(.*)\.[a-z0-9]{2,3}$", options.output)
    if filename:
        options.output = "%s.srt" % filename.group(1)
    else:
        options.output = "%s.srt" % options.output

    log.info("Subtitle: %s", options.output)
    if os.path.isfile(options.output) and not options.force:
        log.info("File already exists. use --force to overwrite")
        return
    fd = open(options.output, "w")
    fd.write(data)
    fd.close()
예제 #20
0
    def sublanguage(self):
        # parse() function partly borrowed from a guy on github. /thanks!
        # https://github.com/riobard/srt.py/blob/master/srt.py
        def parse(self):
            def parse_block(block):
                lines   = block.strip('-').split('\n')
                txt     = '\r\n'.join(lines[2:])
                return txt
            return list(map(parse_block,
                        open(self).read().strip().replace('\r', '').split('\n\n')))
        
        def query(self):
            random_sentences = ' '.join(sample(parse(self),8)).replace('\r\n', '')
            url = 'https://whatlanguage.herokuapp.com'
            payload = { "query": random_sentences }
            headers = {'content-type': 'application/json'} # Note: requests handles json from version 2.4.2 and onwards so i use json.dumps for now.
            try:
                r = post(url, data=dumps(payload), headers=headers, timeout=30) # Note: reasonable timeout i guess? svtplay-dl is mainly used while multitasking i presume, and it is heroku after all (fast enough)
                if r.status_code == codes.ok:
                    try:
                        response = r.json()
                        return response['language']
                    except TypeError:
                        return 'und'
                else:
                    log.error("Server error appeared. Setting language as undetermined.")
                    return 'und'
            except Timeout:
                log.error("30 seconds server timeout reached. Setting language as undetermined.")
                return 'und'

        langs = []
        exceptions = {
            'lulesamiska': 'smj',
            'meankieli': 'fit',
            'jiddisch': 'yid'
        }
        if len(self.subfixes) >= 2:
            log.info("Determining the languages of the subtitles.")
        else: log.info("Determining the language of the subtitle.")
        if self.get_all_subtitles:
            from re import match
            for subfix in self.subfixes:
                if [exceptions[key] for key in exceptions.keys() if match(key, subfix.strip('-'))]:
                    if 'oversattning' in subfix.strip('-'):
                        subfix = subfix.strip('-').split('.')[0]
                    else:
                        subfix = subfix.strip('-')
                    langs += [exceptions[subfix]]
                    continue
                subfile = "{}.srt".format(os.path.splitext(self.stream.options.output)[0] + subfix)
                langs += [query(subfile)]
        else:
            subfile = "{}.srt".format(os.path.splitext(self.stream.options.output)[0])
            langs += [query(subfile)]
        if len(langs) >= 2:
            log.info("Language codes: " + ', '.join(langs))
        else: log.info("Language code: " + langs[0])
        return langs
예제 #21
0
    def remux(self):
        if self.detect is None:
            log.error("Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        if formatname(self.stream.output, self.config, self.stream.output_extention).endswith('.mp4') is False:
            orig_filename = formatname(self.stream.output, self.config, self.stream.output_extention)
            name, ext = os.path.splitext(orig_filename)
            new_name = u"{0}.mp4".format(name)

            cmd = [self.detect, "-i", orig_filename]
            _, stdout, stderr = run_program(cmd, False)  # return 1 is good here.
            videotrack, audiotrack = self._checktracks(stderr)

            if self.config.get("merge_subtitle"):
                log.info(u"Muxing {0} and merging its subtitle into {1}".format(orig_filename, new_name))
            else:
                log.info(u"Muxing {0} into {1}".format(orig_filename, new_name))

            tempfile = u"{0}.temp".format(orig_filename)
            arguments = ["-map", "0:{}".format(videotrack), "-map", "0:{}".format(audiotrack), "-c", "copy", "-f", "mp4"]
            if ext == ".ts":
                arguments += ["-bsf:a", "aac_adtstoasc"]

            if self.config.get("merge_subtitle"):
                langs = self.sublanguage()
                for stream_num, language in enumerate(langs):
                    arguments += ["-map", str(stream_num + 1), "-c:s:" + str(stream_num), "mov_text",
                                  "-metadata:s:s:" + str(stream_num), "language=" + language]
                if self.subfixes and len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{0}.srt".format(name + subfix)
                        cmd += ["-i", subfile]
                else:
                    subfile = "{0}.srt".format(name)
                    cmd += ["-i", subfile]

            arguments += ["-y", tempfile]
            cmd += arguments
            returncode, stdout, stderr = run_program(cmd)
            if returncode != 0:
                return

            if self.config.get("merge_subtitle") and not self.config.get("subtitle"):
                log.info("Muxing done, removing the old files.")
                if self.subfixes and len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{0}.srt".format(name + subfix)
                        os.remove(subfile)
                else:
                    os.remove(subfile)
            else:
                log.info("Muxing done, removing the old file.")
            os.remove(orig_filename)
            os.rename(tempfile, new_name)
예제 #22
0
    def remux(self):
        if self.detect is None:
            log.error("Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        if formatname(self.stream.output, self.config, self.stream.output_extention).endswith('.mp4') is False:
            orig_filename = formatname(self.stream.output, self.config, self.stream.output_extention)
            name, ext = os.path.splitext(orig_filename)
            new_name = u"{0}.mp4".format(name)

            cmd = [self.detect, "-i", orig_filename]
            _, stdout, stderr = run_program(cmd, False)  # return 1 is good here.
            videotrack, audiotrack = self._checktracks(stderr)

            if self.config.get("merge_subtitle"):
                log.info(u"Muxing {0} and merging its subtitle into {1}".format(orig_filename, new_name))
            else:
                log.info(u"Muxing {0} into {1}".format(orig_filename, new_name))

            tempfile = u"{0}.temp".format(orig_filename)
            arguments = ["-map", "0:{}".format(videotrack), "-map", "0:{}".format(audiotrack), "-c", "copy", "-f", "mp4"]
            if ext == ".ts":
                arguments += ["-bsf:a", "aac_adtstoasc"]

            if self.config.get("merge_subtitle"):
                langs = self.sublanguage()
                for stream_num, language in enumerate(langs):
                    arguments += ["-map", str(stream_num + 1), "-c:s:" + str(stream_num), "mov_text",
                                  "-metadata:s:s:" + str(stream_num), "language=" + language]
                if self.subfixes and len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{0}.srt".format(name + subfix)
                        cmd += ["-i", subfile]
                else:
                    subfile = "{0}.srt".format(name)
                    cmd += ["-i", subfile]

            arguments += ["-y", tempfile]
            cmd += arguments
            returncode, stdout, stderr = run_program(cmd)
            if returncode != 0:
                return

            if self.config.get("merge_subtitle") and not self.config.get("subtitle"):
                log.info("Muxing done, removing the old files.")
                if self.subfixes and len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{0}.srt".format(name + subfix)
                        os.remove(subfile)
                else:
                    os.remove(subfile)
            else:
                log.info("Muxing done, removing the old file.")
            os.remove(orig_filename)
            os.rename(tempfile, new_name)
예제 #23
0
    def download(self):
        """ Get the stream from HTTP """
        request = Request(self.url)
        request.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
        try:
            response = urlopen(request)
        except HTTPError as e:
            log.error("Something wrong with that url")
            log.error("Error code: %s", e.code)
            sys.exit(5)
        try:
            total_size = response.info()['Content-Length']
        except KeyError:
            total_size = 0
        total_size = int(total_size)
        bytes_so_far = 0
        if self.options.output != "-":
            extension = re.search(r"(\.[a-z0-9]+)$", self.url)
            if extension:
                self.options.output = self.options.output + extension.group(1)
            else:
                self.options.output = "%s.mp4" % self.options.output
            log.info("Outfile: %s", self.options.output)
            if os.path.isfile(self.options.output) and not self.options.force:
                log.info("File already exists. use --force to overwrite")
                return
            file_d = open(self.options.output, "wb")
        else:
            file_d = sys.stdout

        lastprogress = 0
        while 1:
            chunk = response.read(8192)
            bytes_so_far += len(chunk)

            if not chunk:
                break

            file_d.write(chunk)
            if self.options.output != "-":
                now = time.time()
                if lastprogress + 1 < now:
                    lastprogress = now
                    progress(bytes_so_far, total_size)

        if self.options.output != "-":
            file_d.close()
예제 #24
0
    def remux(self):
        if self.detect is None:
            log.error("Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        if self.stream.options.output.endswith('.mp4') is False:
            orig_filename = self.stream.options.output
            name, ext = os.path.splitext(orig_filename)
            new_name = u"{0}.mp4".format(name)

            if self.merge_subtitle:
                log.info(u"Muxing %s and merging its subtitle into %s", orig_filename, new_name)
            else:
                log.info(u"Muxing %s into %s".format(orig_filename, new_name))

            tempfile = u"{0}.temp".format(orig_filename)
            arguments = ["-map", "0:v", "-map", "0:a", "-c", "copy", "-copyts", "-f", "mp4"]
            if ext == ".ts":
                arguments += ["-bsf:a", "aac_adtstoasc"]
            cmd = [self.detect, "-i", orig_filename]

            if self.merge_subtitle:
                langs = self.sublanguage()
                for stream_num, language in enumerate(langs):
                    arguments += ["-map", str(stream_num + 1), "-c:s:" + str(stream_num), "mov_text", "-metadata:s:s:" + str(stream_num), "language=" + language]
                if len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{0}.srt".format(name + subfix)
                        cmd += ["-i", subfile]
                else:
                    subfile = "{0}.srt".format(name)
                    cmd += ["-i", subfile]

            arguments += ["-y", tempfile]
            cmd += arguments
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
            stdout, stderr = p.communicate()
            if p.returncode != 0:
                stderr = stderr.decode('utf-8', 'replace')
                msg = stderr.strip().split('\n')[-1]
                log.error("Something went wrong: %s", msg)
                return

            if self.merge_subtitle and not self.external_subtitle:
                log.info("Muxing done, removing the old files.")
                if len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{0}.srt".format(name + subfix)
                        os.remove(subfile)
                else: os.remove(subfile)
            else: log.info("Muxing done, removing the old file.")
            os.remove(orig_filename)
            os.rename(tempfile, new_name)
예제 #25
0
    def find_all_episodes(self, options):
        match = re.search(r'<link rel="alternate" type="application/rss\+xml" [^>]*href="([^"]+)"', self.get_urldata())
        if match is None:
            log.info("Couldn't retrieve episode list as rss, trying to scrape")
            return self.scrape_episodes(options)

        url = "http://urplay.se%s" % match.group(1).replace("&amp;", "&")
        xml = ET.XML(self.http.request("get", url).content)

        episodes = [x.text for x in xml.findall(".//item/link")]
        episodes_new = []
        n = 0
        for i in episodes:
            if n == options.all_last:
                break
            if i not in episodes_new:
                episodes_new.append(i)
            n += 1
        return episodes_new
예제 #26
0
def get_media(url, options):
    if "http" not in url[:4]:
        url = "http://%s" % url

    stream = service_handler(sites, options, url)
    if not stream:
        generic = Generic(options, url)
        url, stream = generic.get(sites)
    if not stream:
        if url.find(".f4m") > 0 or url.find(".m3u8") > 0:
            stream = Raw(options, url)
        if not stream:
            log.error("That site is not supported. Make a ticket or send a message")
            sys.exit(2)

    if options.all_episodes:
        if options.output and os.path.isfile(options.output):
            log.error("Output must be a directory if used with --all-episodes")
            sys.exit(2)
        elif options.output and not os.path.exists(options.output):
            try:
                os.makedirs(options.output)
            except OSError as e:
                log.error("%s: %s" % (e.strerror, e.filename))
                return

        episodes = stream.find_all_episodes(options)
        if episodes is None:
            return
        for idx, o in enumerate(episodes):
            if o == url:
                substream = stream
            else:
                substream = service_handler(sites, options, o)

            log.info("Episode %d of %d", idx + 1, len(episodes))

            # get_one_media overwrites options.output...
            get_one_media(substream, copy.copy(options))
    else:
        get_one_media(stream, options)
예제 #27
0
    def find_all_episodes(self, options):
        match = re.search(
            r'<link rel="alternate" type="application/rss\+xml" [^>]*href="([^"]+)"',
            self.get_urldata())
        if match is None:
            log.info("Couldn't retrieve episode list as rss, trying to scrape")
            return self.scrape_episodes(options)

        url = "http://urplay.se%s" % match.group(1).replace("&amp;", "&")
        xml = ET.XML(self.http.request("get", url).content)

        episodes = [x.text for x in xml.findall(".//item/link")]
        episodes_new = []
        n = 0
        for i in episodes:
            if n == options.all_last:
                break
            if i not in episodes_new:
                episodes_new.append(i)
            n += 1
        return episodes_new
예제 #28
0
def output(options, extention="mp4", openfd=True, mode="wb", **kwargs):
    if is_py2:
        file_d = file
    else:
        file_d = io.IOBase

    if options.output != "-":
        ext = re.search(r"(\.\w{2,3})$", options.output)
        if not ext:
            options.output = "%s.%s" % (options.output, extention)
        if options.output_auto and ext:
            options.output = "%s.%s" % (options.output, extention)
        if extention == "srt" and ext:
            options.output = "%s.srt" % options.output[:options.output.
                                                       rfind(ext.group(1))]
        log.info("Outfile: %s", options.output)
        if os.path.isfile(options.output) or \
                findexpisode(os.path.dirname(os.path.realpath(options.output)), options.service, os.path.basename(options.output)):
            if extention == "srt":
                if not options.force_subtitle:
                    log.error(
                        "File (%s) already exists. Use --force-subtitle to overwrite"
                        % options.output)
                    return None
            else:
                if not options.force:
                    log.error(
                        "File (%s) already exists. Use --force to overwrite" %
                        options.output)
                    return None
        if openfd:
            file_d = open(options.output, mode, **kwargs)
    else:
        if openfd:
            if is_py2:
                file_d = sys.stdout
            else:
                file_d = sys.stdout.buffer

    return file_d
예제 #29
0
파일: __init__.py 프로젝트: olof/svtplay-dl
    def merge(self):
        if self.detect is None:
            log.error("Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        orig_filename = self.stream.options.output

        cmd = [self.detect, "-i", orig_filename]
        _, stdout, stderr = run_program(cmd, False)  # return 1 is good here.
        videotrack, audiotrack = self._checktracks(stderr)

        if self.merge_subtitle:
            log.info("Merge audio, video and subtitle into {0}".format(orig_filename))
        else:
            log.info("Merge audio and video into {0}".format(orig_filename))

        tempfile = u"{0}.temp".format(orig_filename)
        name, ext = os.path.splitext(orig_filename)
        arguments = ["-c:v", "copy", "-c:a", "copy", "-f", "mp4"]
        if ext == ".ts":
            audio_filename = u"{0}.audio.ts".format(name)
            arguments += ["-bsf:a", "aac_adtstoasc"]
        else:
            audio_filename = u"{0}.m4a".format(name)
        cmd = [self.detect, "-i", orig_filename, "-i", audio_filename]

        if self.merge_subtitle:
            langs = self.sublanguage()
            for stream_num, language in enumerate(langs, start=audiotrack + 1):
                arguments += ["-map", "{}".format(videotrack), "-map", "{}".format(audiotrack), "-map", str(stream_num), "-c:s:" + str(stream_num - 2), "mov_text",
                              "-metadata:s:s:" + str(stream_num - 2), "language=" + language]
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{0}.srt".format(name + subfix)
                    cmd += ["-i", subfile]
            else:
                subfile = "{0}.srt".format(name)
                cmd += ["-i", subfile]

        arguments += ["-y", tempfile]
        cmd += arguments
        returncode, stdout, stderr = run_program(cmd)
        if returncode != 1:
            return

        log.info("Merging done, removing old files.")
        os.remove(orig_filename)
        os.remove(audio_filename)
        if self.merge_subtitle and not self.external_subtitle:
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{0}.srt".format(name + subfix)
                    os.remove(subfile)
            else:
                os.remove(subfile)
        os.rename(tempfile, orig_filename)
예제 #30
0
    def download(self):
        """ Get the stream from RTMP """
        args = []
        if self.options.live:
            args.append("-v")

        if self.options.resume:
            args.append("-e")

        extension = re.search(r"(\.[a-z0-9]+)$", self.url)
        if self.options.output != "-":
            if not extension:
                self.options.output = "%s.flv" % self.options.output
            else:
                self.options.output = self.options.output + extension.group(1)
            log.info("Outfile: %s", self.options.output)
            if os.path.isfile(self.options.output) and not self.options.force:
                log.info("File already exists. use --force to overwrite")
                return
            args += ["-o", self.options.output]
        if self.options.silent or self.options.output == "-":
            args.append("-q")
        if self.options.other:
            if is_py2:
                args += shlex.split(self.options.other.encode("utf-8"))
            else:
                args += shlex.split(self.options.other)

        if self.options.verbose:
            args.append("-V")

        command = ["rtmpdump", "-r", self.url] + args
        log.debug("Running: %s", " ".join(command))
        try:
            subprocess.call(command)
        except OSError as e:
            log.error("Could not execute rtmpdump: " + e.strerror)
예제 #31
0
    def merge(self):
        if self.detect is None:
            log.error("Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        orig_filename = self.stream.options.output
        if self.merge_subtitle:
            log.info("Merge audio, video and subtitle into %s", orig_filename)
        else:
            log.info("Merge audio and video into %s", orig_filename)

        tempfile = u"{0}.temp".format(orig_filename)
        name = os.path.splitext(orig_filename)[0]
        audio_filename = u"{0}.m4a".format(name)
        arguments = ["-c:v", "copy", "-c:a", "copy", "-f", "mp4"]
        cmd = [self.detect, "-i", orig_filename, "-i", audio_filename]

        if self.merge_subtitle:
            langs = self.sublanguage()
            for stream_num, language in enumerate(langs, start=2):
                arguments += ["-map", "0", "-map", "1", "-map", str(stream_num), "-c:s:" + str(stream_num - 2), "mov_text", "-metadata:s:s:" + str(stream_num - 2), "language=" + language]
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{0}.srt".format(name + subfix)
                    cmd += ["-i", subfile]
            else:
                subfile = "{0}.srt".format(name)
                cmd += ["-i", subfile]

        arguments += ["-y", tempfile]
        cmd += arguments
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        stdout, stderr = p.communicate()
        if p.returncode != 0:
            stderr = stderr.decode('utf-8', 'replace')
            msg = stderr.strip().split('\n')[-1]
            log.error("Something went wrong: %s", msg)
            return

        log.info("Merging done, removing old files.")
        os.remove(orig_filename)
        os.remove(audio_filename)
        if self.merge_subtitle and not self.external_subtitle:
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{0}.srt".format(name + subfix)
                    os.remove(subfile)
            else: os.remove(subfile)
        os.rename(tempfile, orig_filename)
예제 #32
0
    def remux(self):
        if self.detect is None:
            log.error(
                "Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        if self.stream.options.output.endswith('.mp4') is False:
            orig_filename = self.stream.options.output
            name, ext = os.path.splitext(orig_filename)
            new_name = "{}.mp4".format(name)

            if self.merge_subtitle:
                log.info("Muxing %s and merging its subtitle into %s",
                         orig_filename, new_name)
            else:
                log.info("Muxing %s into %s", orig_filename, new_name)

            tempfile = "{}.temp".format(orig_filename)
            arguments = [
                "-map", "0:v", "-map", "0:a", "-c", "copy", "-copyts", "-f",
                "mp4"
            ]
            if ext == ".ts":
                arguments += ["-bsf:a", "aac_adtstoasc"]
            cmd = [self.detect, "-i", orig_filename]

            if self.merge_subtitle:
                langs = self.sublanguage()
                for stream_num, language in enumerate(langs):
                    arguments += [
                        "-map",
                        str(stream_num + 1), "-c:s:" + str(stream_num),
                        "mov_text", "-metadata:s:s:" + str(stream_num),
                        "language=" + language
                    ]
                if len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{}.srt".format(name + subfix)
                        cmd += ["-i", subfile]
                else:
                    subfile = "{}.srt".format(name)
                    cmd += ["-i", subfile]

            arguments += ["-y", tempfile]
            cmd += arguments
            p = subprocess.Popen(cmd,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 stdin=subprocess.PIPE)
            stdout, stderr = p.communicate()
            if p.returncode != 0:
                stderr = stderr.decode('utf-8', 'replace')
                msg = stderr.strip().split('\n')[-1]
                log.error("Something went wrong: %s", msg)
                return

            if self.merge_subtitle and not self.external_subtitle:
                log.info("Muxing done, removing the old files.")
                if len(self.subfixes) >= 2:
                    for subfix in self.subfixes:
                        subfile = "{}.srt".format(name + subfix)
                        os.remove(subfile)
                else:
                    os.remove(subfile)
            else:
                log.info("Muxing done, removing the old file.")
            os.remove(orig_filename)
            os.rename(tempfile, new_name)
예제 #33
0
    def sublanguage(self):
        # parse() function partly borrowed from a guy on github. /thanks!
        # https://github.com/riobard/srt.py/blob/master/srt.py
        def parse(self):
            def parse_block(block):
                lines = block.strip('-').split('\n')
                txt = '\r\n'.join(lines[2:])
                return txt

            return map(
                parse_block,
                open(self).read().strip().replace('\r', '').split('\n\n'))

        def query(self):
            random_sentences = ' '.join(sample(parse(self),
                                               8)).replace('\r\n', '')
            url = 'https://whatlanguage.herokuapp.com'
            payload = {"query": random_sentences}
            headers = {
                'content-type': 'application/json'
            }  # Note: requests handles json from version 2.4.2 and onwards so i use json.dumps for now.
            try:
                r = post(
                    url, data=dumps(payload), headers=headers, timeout=30
                )  # Note: reasonable timeout i guess? svtplay-dl is mainly used while multitasking i presume, and it is heroku after all (fast enough)
                if r.status_code == codes.ok:
                    response = r.json()
                    return response['language']
                else:
                    log.error(
                        "Server error appeared. Setting language as undetermined."
                    )
                    return 'und'
            except Timeout:
                log.error(
                    "30 seconds server timeout reached. Setting language as undetermined."
                )
                return 'und'

        langs = []
        exceptions = {
            'lulesamiska': 'smj',
            'meankieli': 'fit',
            'jiddisch': 'yid'
        }
        if len(self.subfixes) >= 2:
            log.info("Determining the languages of the subtitles.")
        else:
            log.info("Determining the language of the subtitle.")
        if self.get_all_subtitles:
            from re import match
            for subfix in self.subfixes:
                if [
                        exceptions[key] for key in exceptions.keys()
                        if match(key, subfix.strip('-'))
                ]:
                    if 'oversattning' in subfix.strip('-'):
                        subfix = subfix.strip('-').split('.')[0]
                    else:
                        subfix = subfix.strip('-')
                    langs += [exceptions[subfix]]
                    continue
                subfile = "{}.srt".format(
                    os.path.splitext(self.stream.options.output)[0] + subfix)
                langs += [query(subfile)]
        else:
            subfile = "{}.srt".format(
                os.path.splitext(self.stream.options.output)[0])
            langs += [query(subfile)]
        if len(langs) >= 2:
            log.info("Language codes: " + ', '.join(langs))
        else:
            log.info("Language code: " + langs[0])
        return langs
예제 #34
0
    def merge(self):
        if self.detect is None:
            log.error(
                "Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        orig_filename = self.stream.options.output
        if self.merge_subtitle:
            log.info("Merge audio, video and subtitle into %s", orig_filename)
        else:
            log.info("Merge audio and video into %s", orig_filename)

        tempfile = "{}.temp".format(orig_filename)
        name = os.path.splitext(orig_filename)[0]
        audio_filename = "{}.m4a".format(name)
        arguments = ["-c:v", "copy", "-c:a", "copy", "-f", "mp4"]
        cmd = [self.detect, "-i", orig_filename, "-i", audio_filename]

        if self.merge_subtitle:
            langs = self.sublanguage()
            for stream_num, language in enumerate(langs, start=2):
                arguments += [
                    "-map", "0", "-map", "1", "-map",
                    str(stream_num), "-c:s:" + str(stream_num - 2), "mov_text",
                    "-metadata:s:s:" + str(stream_num - 2),
                    "language=" + language
                ]
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{}.srt".format(name + subfix)
                    cmd += ["-i", subfile]
            else:
                subfile = "{}.srt".format(name)
                cmd += ["-i", subfile]

        arguments += ["-y", tempfile]
        cmd += arguments
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE)
        stdout, stderr = p.communicate()
        if p.returncode != 0:
            stderr = stderr.decode('utf-8', 'replace')
            msg = stderr.strip().split('\n')[-1]
            log.error("Something went wrong: %s", msg)
            return

        log.info("Merging done, removing old files.")
        os.remove(orig_filename)
        os.remove(audio_filename)
        if self.merge_subtitle and not self.external_subtitle:
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{}.srt".format(name + subfix)
                    os.remove(subfile)
            else:
                os.remove(subfile)
        os.rename(tempfile, orig_filename)
예제 #35
0
def get_one_media(stream):
    # Make an automagic filename
    if not filename(stream):
        return

    if stream.config.get("merge_subtitle"):
        if not which('ffmpeg'):
            log.error("--merge-subtitle needs ffmpeg. Please install ffmpeg.")
            log.info("https://ffmpeg.org/download.html")
            sys.exit(2)

    videos = []
    subs = []
    subfixes = []
    error = []
    streams = stream.get()
    try:
        for i in streams:
            if isinstance(i, Exception):
                error.append(i)
            elif not exclude(stream.config, formatname(i.output,
                                                       stream.config)):
                if isinstance(i, VideoRetriever):
                    if stream.config.get("preferred"):
                        if stream.config.get("preferred").lower() == i.name:
                            videos.append(i)
                    else:
                        videos.append(i)
                if isinstance(i, subtitle):
                    subs.append(i)
    except Exception as e:
        if stream.config.get("verbose"):
            raise
        else:
            logging.error("svtplay-dl crashed")
            logging.error(
                "Run again and add --verbose as an argument, to get more information"
            )
            logging.error(
                "If the error persists, you can report it at https://github.com/spaam/svtplay-dl/issues"
            )
            logging.error(
                "Include the URL used, the stack trace and the output of svtplay-dl --version in the issue"
            )
        return

    if stream.config.get("require_subtitle") and not subs:
        logging.info("No subtitles available")
        return

    if stream.config.get("subtitle") and stream.config.get("get_url"):
        if subs:
            if stream.config.get("get_all_subtitles"):
                for sub in subs:
                    print(sub.url)
            else:
                print(subs[0].url)
        if stream.config.get("force_subtitle"):
            return

    def options_subs_dl(subfixes):
        if subs:
            if stream.config.get("get_all_subtitles"):
                for sub in subs:
                    sub.download()
                    if stream.config.get("merge_subtitle"):
                        if sub.subfix:
                            subfixes += [sub.subfix]
                        else:
                            stream.config.set("get_all_subtitles", False)
            else:
                subs[0].download()
        elif stream.config.get("merge_subtitle"):
            stream.config.set("merge_subtitle", False)

    if stream.config.get("subtitle") and not stream.config.get("get_url"):
        options_subs_dl(subfixes)
        if stream.config.get("force_subtitle"):
            return

    if stream.config.get(
            "merge_subtitle") and not stream.config.get("subtitle"):
        options_subs_dl(subfixes)

    if not videos:
        errormsg = None
        for exc in error:
            if errormsg:
                errormsg = "{}. {}".format(errormsg, str(exc))
            else:
                errormsg = str(exc)
        logging.error("No videos found. {}".format(errormsg))
    else:
        if stream.config.get("list_quality"):
            list_quality(videos)
            return
        try:
            stream = select_quality(stream.config, videos)
            if stream.config.get("get_url"):
                print(stream.url)
                return
            logging.info("Selected to download %s, bitrate: %s", stream.name,
                         stream.bitrate)
            stream.download()
        except UIException as e:
            if stream.config.get("verbose"):
                raise e
            log.error(e)
            sys.exit(2)

        if stream.config.get("thumbnail") and hasattr(stream, "get_thumbnail"):
            stream.get_thumbnail(stream.config)
        post = postprocess(stream, stream.config, subfixes)
        if stream.audio and post.detect:
            post.merge()
        if stream.audio and not post.detect and stream.finished:
            logging.warning(
                "Cant find ffmpeg/avconv. audio and video is in seperate files. if you dont want this use -P hls or hds"
            )
        if stream.name == "hls" or stream.config.get("remux"):
            post.remux()
        if stream.config.get("silent_semi") and stream.finished:
            logging.log(25,
                        "Download of %s was completed" % stream.options.output)
예제 #36
0
    def find_all_episodes(self, options):
        parse = urlparse(self._url)

        if len(parse.path) > 7 and parse.path[-7:] == "rss.xml":
            rss_url = self.url
        else:
            rss_url = re.search(
                r'<link rel="alternate" type="application/rss\+xml" [^>]*href="([^"]+)"',
                self.get_urldata())
            if rss_url:
                rss_url = rss_url.group(1)

        valid_rss = False
        tab = None
        if parse.query:
            match = re.search("tab=(.+)", parse.query)
            if match:
                tab = match.group(1)

        #Clips and tab can not be used with RSS-feed
        if rss_url and not self.options.include_clips and not tab:
            rss_data = self.http.request("get", rss_url).content

            try:
                xml = ET.XML(rss_data)
                episodes = [x.text for x in xml.findall(".//item/link")]
                #TODO add better checks for valid RSS-feed here
                valid_rss = True
            except ET.ParseError:
                log.info(
                    "Error parsing RSS-feed at %s, make sure it is a valid RSS-feed, will use other method to find episodes."
                    % rss_url)
        else:
            #if either tab or include_clips is set remove rss.xml from url if set manually.
            if len(parse.path) > 7 and parse.path[-7:] == "rss.xml":
                self._url = self.url.replace("rss.xml", "")

        if not valid_rss:
            videos = []
            tab = None
            match = re.search("__svtplay'] = ({.*});", self.get_urldata())
            if re.search("sista-chansen", parse.path):
                videos = self._last_chance(videos, 1)
            elif not match:
                log.error("Couldn't retrieve episode list.")
                return
            else:
                dataj = json.loads(match.group(1))
                if re.search("/genre", parse.path):
                    videos = self._genre(dataj)
                else:
                    if parse.query:
                        match = re.search("tab=(.+)", parse.query)
                        if match:
                            tab = match.group(1)

                    items = dataj["relatedVideoContent"][
                        "relatedVideosAccordion"]
                    for i in items:
                        if tab:
                            if i["slug"] == tab:
                                videos = self.videos_to_list(
                                    i["videos"], videos)
                        else:
                            if "klipp" not in i[
                                    "slug"] and "kommande" not in i["slug"]:
                                videos = self.videos_to_list(
                                    i["videos"], videos)
                        if self.options.include_clips:
                            if i["slug"] == "klipp":
                                videos = self.videos_to_list(
                                    i["videos"], videos)

            episodes = [urljoin("http://www.svtplay.se", x) for x in videos]

        if options.all_last > 0:
            return sorted(episodes[-options.all_last:])
        return sorted(episodes)
예제 #37
0
    def find_all_episodes(self, options):
        parse = urlparse(self._url)
        
        if len(parse.path) > 7 and parse.path[-7:] == "rss.xml":
            rss_url = self.url
        else:
            rss_url = re.search(r'<link rel="alternate" type="application/rss\+xml" [^>]*href="([^"]+)"', self.get_urldata())
            if rss_url: 
                rss_url = rss_url.group(1)

        valid_rss = False
        tab = None
        if parse.query:
            match = re.search("tab=(.+)", parse.query)
            if match:
                tab = match.group(1)

        #Clips and tab can not be used with RSS-feed
        if rss_url and not self.options.include_clips and not tab:
            rss_data = self.http.request("get", rss_url).content

            try:
                xml = ET.XML(rss_data)
                episodes = [x.text for x in xml.findall(".//item/link")]
                #TODO add better checks for valid RSS-feed here
                valid_rss = True
            except ET.ParseError:
                log.info("Error parsing RSS-feed at {0}, make sure it is a valid RSS-feed, will use other method to find episodes.".format(rss_url))
        else:
            #if either tab or include_clips is set remove rss.xml from url if set manually. 
            if len(parse.path) > 7 and parse.path[-7:] == "rss.xml":                
                self._url = self.url.replace("rss.xml","")

        if not valid_rss:
            videos = []
            tab = None
            match = re.search("__svtplay'] = ({.*});", self.get_urldata())
            if re.search("sista-chansen", parse.path):
                videos = self._last_chance(videos, 1)
            elif not match:
                log.error("Couldn't retrieve episode list.")
                return
            else:
                dataj = json.loads(match.group(1))
                if re.search("/genre", parse.path):
                    videos = self._genre(dataj)
                else:
                    if parse.query:
                        match = re.search("tab=(.+)", parse.query)
                        if match:
                            tab = match.group(1)
                            
                    items = dataj["relatedVideoContent"]["relatedVideosAccordion"]
                    for i in items:
                        if tab:
                            if i["slug"] == tab:
                                videos = self.videos_to_list(i["videos"], videos)
                        else:
                            if "klipp" not in i["slug"] and "kommande" not in i["slug"]:
                                videos = self.videos_to_list(i["videos"], videos)
                        if self.options.include_clips: 
                            if i["slug"] == "klipp":
                                videos = self.videos_to_list(i["videos"], videos)

            episodes = [urljoin("http://www.svtplay.se", x) for x in videos]

        if options.all_last > 0:
            return sorted(episodes)[-options.all_last:]
        return sorted(episodes)
예제 #38
0
    def merge(self):
        if self.detect is None:
            log.error(
                "Cant detect ffmpeg or avconv. Cant mux files without it.")
            return
        if self.stream.finished is False:
            return

        orig_filename = self.stream.options.output

        cmd = [self.detect, "-i", orig_filename]
        _, stdout, stderr = run_program(cmd, False)  # return 1 is good here.
        videotrack, audiotrack = self._checktracks(stderr)

        if self.merge_subtitle:
            log.info("Merge audio, video and subtitle into {0}".format(
                orig_filename))
        else:
            log.info("Merge audio and video into {0}".format(orig_filename))

        tempfile = u"{0}.temp".format(orig_filename)
        name = os.path.splitext(orig_filename)[0]
        audio_filename = u"{0}.m4a".format(name)
        arguments = ["-c:v", "copy", "-c:a", "copy", "-f", "mp4"]
        cmd = [self.detect, "-i", orig_filename, "-i", audio_filename]

        if self.merge_subtitle:
            langs = self.sublanguage()
            for stream_num, language in enumerate(langs, start=audiotrack + 1):
                arguments += [
                    "-map", "{}".format(videotrack), "-map",
                    "{}".format(audiotrack), "-map",
                    str(stream_num), "-c:s:" + str(stream_num - 2), "mov_text",
                    "-metadata:s:s:" + str(stream_num - 2),
                    "language=" + language
                ]
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{0}.srt".format(name + subfix)
                    cmd += ["-i", subfile]
            else:
                subfile = "{0}.srt".format(name)
                cmd += ["-i", subfile]

        arguments += ["-y", tempfile]
        cmd += arguments
        returncode, stdout, stderr = run_program(cmd)
        if returncode != 1:
            return

        log.info("Merging done, removing old files.")
        os.remove(orig_filename)
        os.remove(audio_filename)
        if self.merge_subtitle and not self.external_subtitle:
            if len(self.subfixes) >= 2:
                for subfix in self.subfixes:
                    subfile = "{0}.srt".format(name + subfix)
                    os.remove(subfile)
            else:
                os.remove(subfile)
        os.rename(tempfile, orig_filename)
예제 #39
0
def get_one_media(stream, options):
    # Make an automagic filename
    if not filename(stream):
        return

    videos = []
    subs = []
    error = []
    streams = stream.get()
    try:
        for i in streams:
            if isinstance(i, VideoRetriever):
                if options.preferred:
                    if options.preferred.lower() == i.name():
                        videos.append(i)
                else:
                    videos.append(i)
            if isinstance(i, subtitle):
                subs.append(i)
            if isinstance(i, Exception):
                error.append(i)
    except Exception as e:
        if options.verbose:
            raise
        else:
            log.error("svtplay-dl crashed")
            log.error("Run again and add --verbose as an argument, to get more information")
            log.error("If the error persists, you can report it at https://github.com/spaam/svtplay-dl/issues")
            log.error("Include the URL used, the stack trace and the output of svtplay-dl --version in the issue")
        sys.exit(3)

    if options.require_subtitle and not subs:
        log.info("No subtitles available")
        return

    if options.subtitle and options.output != "-":
        if subs:
            subs[0].download()
        if options.force_subtitle:
            return

    if len(videos) == 0:
        for exc in error:
            log.error(str(exc))
    else:
        if options.list_quality:
            list_quality(videos)
            return
        stream = select_quality(options, videos)
        log.info("Selected to download %s, bitrate: %s",
                 stream.name(), stream.bitrate)
        if options.get_url:
            print(stream.url)
            return
        try:
            stream.download()
        except UIException as e:
            if options.verbose:
                raise e
            log.error(e)
            sys.exit(2)

        if options.thumbnail and hasattr(stream, "get_thumbnail"):
            if options.output != "-":
                log.info("Getting thumbnail")
                stream.get_thumbnail(options)
            else:
                log.warning("Can not get thumbnail when fetching to stdout")
        post = postprocess(stream)
        if stream.name() == "dash" and post.detect:
            post.merge()
        if stream.name() == "dash" and not post.detect and stream.finished:
            log.warning("Cant find ffmpeg/avconv. audio and video is in seperate files. if you dont want this use -P hls or hds")
        if options.remux:
            post.remux()
예제 #40
0
def get_one_media(stream, options):
    # Make an automagic filename
    if not filename(stream):
        return

    if options.merge_subtitle:
        from svtplay_dl.utils import which
        if not which('ffmpeg'):
            log.error("--merge-subtitle needs ffmpeg. Please install ffmpeg.")
            log.info("https://ffmpeg.org/download.html")
            sys.exit(2)

    videos = []
    subs = []
    subfixes = []
    error = []
    streams = stream.get()
    try:
        for i in streams:
            if isinstance(i, VideoRetriever):
                if options.preferred:
                    if options.preferred.lower() == i.name():
                        videos.append(i)
                else:
                    videos.append(i)
            if isinstance(i, subtitle):
                subs.append(i)
            if isinstance(i, Exception):
                error.append(i)
    except Exception as e:
        if options.verbose:
            log.error("version: %s" % __version__)
            raise
        else:
            log.error("svtplay-dl crashed")
            log.error("Run again and add --verbose as an argument, to get more information")
            log.error("If the error persists, you can report it at https://github.com/spaam/svtplay-dl/issues")
            log.error("Include the URL used, the stack trace and the output of svtplay-dl --version in the issue")
        sys.exit(3)

    if options.require_subtitle and not subs:
        log.info("No subtitles available")
        return

    if options.subtitle and options.get_url:
        if subs:
            if options.get_all_subtitles:
                for sub in subs:
                    print(sub.url)
            else:
                print(subs[0].url)
        if options.force_subtitle: 
            return

    def options_subs_dl(subfixes):
        if subs:
            if options.get_all_subtitles:
                for sub in subs:
                    sub.download()
                    if options.merge_subtitle:
                        if sub.subfix:
                            subfixes += [sub.subfix]
                        else:
                            options.get_all_subtitles = False
            else: 
                subs[0].download()
        elif options.merge_subtitle:
            options.merge_subtitle = False

    if options.subtitle and options.output != "-" and not options.get_url:
        options_subs_dl(subfixes)
        if options.force_subtitle:
            return

    if options.merge_subtitle and not options.subtitle:
        options_subs_dl(subfixes)


    if len(videos) == 0:
        for exc in error:
            log.error(str(exc))
    else:
        if options.list_quality:
            list_quality(videos)
            return
        try:
            stream = select_quality(options, videos)
            if options.get_url:
                print(stream.url)
                return
            log.info("Selected to download %s, bitrate: %s",
                     stream.name(), stream.bitrate)
            stream.download()
        except UIException as e:
            if options.verbose:
                raise e
            log.error(e)
            sys.exit(2)

        if options.thumbnail and hasattr(stream, "get_thumbnail"):
            if options.output != "-":
                log.info("Getting thumbnail")
                stream.get_thumbnail(options)
            else:
                log.warning("Can not get thumbnail when fetching to stdout")
        post = postprocess(stream, options, subfixes)
        if stream.name() == "dash" and post.detect:
            post.merge()
        if stream.name() == "dash" and not post.detect and stream.finished:
            log.warning("Cant find ffmpeg/avconv. audio and video is in seperate files. if you dont want this use -P hls or hds")
        if options.remux:
            post.remux()
        if options.silent_semi and stream.finished:
            log.log(25, "Download of %s was completed" % stream.options.output)
예제 #41
0
def get_one_media(stream, options):
    # Make an automagic filename
    if not filename(options, stream):
        return

    videos = []
    subs = []
    error = []
    streams = stream.get(options)
    try:
        for i in streams:
            if isinstance(i, VideoRetriever):
                if options.preferred:
                    if options.preferred.lower() == i.name():
                        videos.append(i)
                else:
                    videos.append(i)
            if isinstance(i, subtitle):
                subs.append(i)
            if isinstance(i, Exception):
                error.append(i)
    except Exception as e:
        if options.verbose:
            raise e
        else:
            print("Script crashed. please run the script again and add --verbose as an argument")
            print("Make an issue with the url you used and include the stacktrace. please include the version of the script")
        sys.exit(3)

    if options.require_subtitle and not subs:
        log.info("No subtitles available")
        return

    if options.subtitle and options.output != "-":
        if subs:
            subs[0].download()
        if options.force_subtitle:
            return

    if len(videos) == 0:
        for exc in error:
            log.error(str(exc))
        sys.exit(2)
    else:
        if options.list_quality:
            list_quality(videos)
            return
        stream = select_quality(options, videos)
        log.info("Selected to download %s, bitrate: %s",
                 stream.name(), stream.bitrate)
        if options.get_url:
            print(stream.url)
            return
        try:
            stream.download()
        except UIException as e:
            if options.verbose:
                raise e
            log.error(e)
            sys.exit(2)

        if options.thumbnail and hasattr(stream, "get_thumbnail"):
            if options.output != "-":
                log.info("Getting thumbnail")
                stream.get_thumbnail(options)
            else:
                log.warning("Can not get thumbnail when fetching to stdout")
예제 #42
0
def get_one_media(stream, options):
    # Make an automagic filename
    if not filename(stream):
        return

    if options.merge_subtitle:
        from svtplay_dl.utils import which
        if not which('ffmpeg'):
            log.error("--merge-subtitle needs ffmpeg. Please install ffmpeg.")
            log.info("https://ffmpeg.org/download.html")
            sys.exit(2)

    videos = []
    subs = []
    subfixes = []
    error = []
    streams = stream.get()
    try:
        for i in streams:
            if isinstance(i, VideoRetriever):
                if options.preferred:
                    if options.preferred.lower() == i.name():
                        videos.append(i)
                else:
                    videos.append(i)
            if isinstance(i, subtitle):
                subs.append(i)
            if isinstance(i, Exception):
                error.append(i)
    except Exception as e:
        if options.verbose:
            raise
        else:
            log.error("svtplay-dl crashed")
            log.error("Run again and add --verbose as an argument, to get more information")
            log.error("If the error persists, you can report it at https://github.com/spaam/svtplay-dl/issues")
            log.error("Include the URL used, the stack trace and the output of svtplay-dl --version in the issue")
        sys.exit(3)

    if options.require_subtitle and not subs:
        log.info("No subtitles available")
        return

    if options.subtitle and options.get_url:
        if subs:
            if options.get_all_subtitles:
                for sub in subs:
                    print(sub.url)
            else:
                print(subs[0].url)
        if options.force_subtitle: 
            return

    def options_subs_dl(subfixes):
        if subs:
            if options.get_all_subtitles:
                for sub in subs:
                    sub.download()
                    if options.merge_subtitle:
                        if sub.subfix:
                            subfixes += [sub.subfix]
                        else:
                            options.get_all_subtitles = False
            else: 
                subs[0].download()
        elif options.merge_subtitle:
            options.merge_subtitle = False

    if options.subtitle and options.output != "-" and not options.get_url:
        options_subs_dl(subfixes)
        if options.force_subtitle:
            return

    if options.merge_subtitle and not options.subtitle:
        options_subs_dl(subfixes)

    if not videos:
        log.error("No videos found.")
        for exc in error:
            log.error(str(exc))
    else:
        if options.list_quality:
            list_quality(videos)
            return
        try:
            stream = select_quality(options, videos)
            if options.get_url:
                print(stream.url)
                return
            log.info("Selected to download %s, bitrate: %s",
                     stream.name(), stream.bitrate)
            stream.download()
        except UIException as e:
            if options.verbose:
                raise e
            log.error(e)
            sys.exit(2)

        if options.thumbnail and hasattr(stream, "get_thumbnail"):
            if options.output != "-":
                log.info("Getting thumbnail")
                stream.get_thumbnail(options)
            else:
                log.warning("Can not get thumbnail when fetching to stdout")
        post = postprocess(stream, options, subfixes)
        if stream.name() == "dash" and post.detect:
            post.merge()
        if stream.name() == "dash" and not post.detect and stream.finished:
            log.warning("Cant find ffmpeg/avconv. audio and video is in seperate files. if you dont want this use -P hls or hds")
        if options.remux:
            post.remux()
        if options.silent_semi and stream.finished:
            log.log(25, "Download of %s was completed" % stream.options.output)
예제 #43
0
파일: hls.py 프로젝트: quite/svtplay-dl
def download_hls(options, url, baseurl=None):
    data = get_http_data(url)
    globaldata, files = parsem3u(data)
    streams = {}
    for i in files:
        streams[int(i[1]["BANDWIDTH"])] = i[0]

    test = select_quality(options, streams)
    if baseurl and test[:4] != 'http':
        test = "%s/%s" % (baseurl, test)
    m3u8 = get_http_data(test)
    globaldata, files = parsem3u(m3u8)
    encrypted = False
    key = None
    try:
        keydata = globaldata["KEY"]
        encrypted = True
    except:
        pass

    if encrypted:
        try:
            from Crypto.Cipher import AES
        except ImportError:
            log.error("You need to install pycrypto to download encrypted HLS streams")
            sys.exit(2)
        match = re.search("URI=\"(http://.*)\"", keydata)
        key = get_http_data(match.group(1))
        rand = os.urandom(16)
        decryptor = AES.new(key, AES.MODE_CBC, rand)
    n = 1
    if options.output != "-":
        extension = re.search("(\.[a-z0-9]+)$", options.output)
        if not extension:
            options.output = "%s.ts" % options.output
        log.info("Outfile: %s", options.output)
        file_d = open(options.output, "wb")
    else:
        file_d = sys.stdout

    start = time.time()
    estimated = ""
    for i in files:
        item = i[0]
        if options.output != "-":
            progressbar(len(files), n, estimated)
        if item[0:5] != "http:":
            item = "%s/%s" % (baseurl, item)
        data = get_http_data(item)
        if encrypted:
            lots = StringIO(data)

            plain = b""
            crypt = lots.read(1024)
            decrypted = decryptor.decrypt(crypt)
            while decrypted:
                plain += decrypted
                crypt = lots.read(1024)
                decrypted = decryptor.decrypt(crypt)
            data = plain

        file_d.write(data)
        now = time.time()
        dt = now - start
        et = dt / (n + 1) * len(files)
        rt = et - dt
        td = timedelta(seconds = int(rt))
        estimated = "Estimated Remaining: " + str(td)
        n += 1

    if options.output != "-":
        file_d.close()
        progress_stream.write('\n')