예제 #1
0
def ffprobe_get_media_duration(file):
    print('Getting {} duration'.format(file))
    params = [FFPROBE]
    params.extend(['-i', file])
    params.extend(['-show_entries', 'format=duration'])
    params.extend(['-v', 'quiet'])
    params.extend(['-of', 'csv=p=0'])
    return subprocess.check_output(
        params, stdin=STDIN, stderr=subprocess.STDOUT
    ).decode().strip()
예제 #2
0
def ffmpeg_download_stream(
    files, title, ext, params={}, output_dir='.', stream=True, **kwargs
):
    """str, str->True
    WARNING: NOT THE SAME PARMS AS OTHER FUNCTIONS!!!!!!
    You can basicly download anything with this function
    but better leave it alone with
    """
    # https://ffmpeg.org/ffmpeg.html#Main-options
    output = '{}.{}'.format(title, ext)

    if not (output_dir == '.'):
        output = '{}/{}'.format(output_dir, output)

    print(
        'Downloading streaming content with FFmpeg, press q to stop '
        'recording...'
    )
    if stream:
        ffmpeg_params = [FFMPEG] + ['-y', '-re', '-i']
    else:
        ffmpeg_params = [FFMPEG] + ['-y', '-i']
    ffmpeg_params.append(files)  # not the same here!!!!

    if FFMPEG == 'avconv':  # who cares?
        ffmpeg_params += ['-c', 'copy', output]
    elif kwargs.get('override'):
        pass
    else:
        ffmpeg_params += ['-c', 'copy', '-bsf:a', 'aac_adtstoasc']

    if params is not None:
        if len(params) > 0:
            for k, v in params.items():
                ffmpeg_params.append(k)
                ffmpeg_params.append(v)

    ffmpeg_params.append(output)

    print(' '.join(ffmpeg_params))

    try:
        a = subprocess.Popen(ffmpeg_params, stdin=subprocess.PIPE)
        a.communicate()
    except KeyboardInterrupt:
        try:
            a.stdin.write('q'.encode('utf-8'))
        except Exception:
            pass

    return True
예제 #3
0
def ffmpeg_concat_av(files, output, ext):
    print('Merging video parts... ', end="", flush=True)
    params = [FFMPEG] + LOGLEVEL
    for file in files:
        if os.path.isfile(file):
            params.extend(['-i', file])
    params.extend(['-c:v', 'copy'])
    if ext == 'mp4':
        params.extend(['-c:a', 'aac'])
    elif ext == 'webm':
        params.extend(['-c:a', 'vorbis'])
    params.extend(['-strict', 'experimental'])
    params.append(output)
    return subprocess.call(params, stdin=STDIN)
예제 #4
0
파일: ffmpeg.py 프로젝트: zzlettle/Lulu
def ffmpeg_concat_audio_and_video(files, output, ext):
    print('Merging video and audio parts... ', end='', flush=True)
    if has_ffmpeg_installed:
        params = [FFMPEG] + LOGLEVEL
        params.extend(['-f', 'concat'])
        for file in files:
            if os.path.isfile(file):
                params.extend(['-i', file])
        params.extend(['-c:v', 'copy'])
        params.extend(['-c:a', 'aac'])
        params.extend(['-strict', 'experimental'])
        params.append('{}.{}'.format(output, ext))
        return subprocess.call(params, stdin=STDIN)
    else:
        raise EnvironmentError('No ffmpeg found')
예제 #5
0
def ffmpeg_concat_ts_to_mkv(files, output='output.mkv'):
    print('Merging video parts... ', end='', flush=True)
    params = [FFMPEG] + LOGLEVEL + ['-isync', '-y', '-i']
    params.append('concat:')
    for file in files:
        if os.path.isfile(file):
            params[-1] += file + '|'
    params += ['-f', 'matroska', '-c', 'copy', output]

    try:
        if subprocess.call(params, stdin=STDIN) == 0:
            return True
        else:
            return False
    except Exception:
        return False
예제 #6
0
def ffmpeg_concat_flv_to_mp4(files, output='output.mp4'):
    print('Merging video parts... ', end='', flush=True)
    # Use concat demuxer on FFmpeg >= 1.1
    if FFMPEG == 'ffmpeg' and (
        FFMPEG_VERSION[0] >= 2 or (
            FFMPEG_VERSION[0] == 1 and FFMPEG_VERSION[1] >= 1
        )
    ):
        concat_list = generate_concat_list(files, output)
        params = [FFMPEG] + LOGLEVEL + [
            '-y', '-f', 'concat', '-safe', '-1', '-i', concat_list, '-c',
            'copy', '-bsf:a', 'aac_adtstoasc', output
        ]
        subprocess.check_call(params, stdin=STDIN)
        os.remove(output + '.txt')
        return True

    for file in files:
        if os.path.isfile(file):
            params = [FFMPEG] + LOGLEVEL + ['-y', '-i']
            params.append(file)
            params += [
                '-map', '0', '-c', 'copy', '-f', 'mpegts', '-bsf:v',
                'h264_mp4toannexb'
            ]
            params.append(file + '.ts')

            subprocess.call(params, stdin=STDIN)

    params = [FFMPEG] + LOGLEVEL + ['-y', '-i']
    params.append('concat:')
    for file in files:
        f = file + '.ts'
        if os.path.isfile(f):
            params[-1] += f + '|'
    if FFMPEG == 'avconv':
        params += ['-c', 'copy', output]
    else:
        params += ['-c', 'copy', '-absf', 'aac_adtstoasc', output]

    if subprocess.call(params, stdin=STDIN) == 0:
        for file in files:
            os.remove(file + '.ts')
        return True
    else:
        raise
예제 #7
0
def get_usable_ffmpeg(cmd):
    try:
        p = subprocess.Popen(
            [cmd, '-version'], stdin=DEVNULL, stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        out, err = p.communicate()
        vers = str(out, 'utf-8').split('\n')[0].split()
        assert (vers[0] == 'ffmpeg' and vers[2][0] > '0') or \
            (vers[0] == 'avconv')
        # set version to 1.0 for nightly build and print warning
        try:
            version = [int(i) for i in vers[2].split('.')]
        except Exception:
            print('It seems that your ffmpeg is a nightly build.')
            print('Please switch to the latest stable if merging failed.')
            version = [1, 0]
        return cmd, 'ffprobe', version
    except Exception:
        return None
예제 #8
0
파일: netease.py 프로젝트: leotop/Lulu
    def netease_lyric_download(self,
                               song,
                               output_dir,
                               info_only,
                               playlist_prefix='',
                               **kwargs):
        if info_only or not kwargs.get('caption'):
            return

        data = json.loads(
            get_content('http://music.163.com/api/song/lyric/?'
                        'id={}&lv=-1&csrf_token='.format(song['id']),
                        headers={'Referer': 'http://music.163.com/'}))
        title = '{}{}. {}'.format(playlist_prefix, song['position'],
                                  song['name'])
        filename = '{}.lrc'.format(get_filename(title))
        print('Saving {} ...'.format(filename), end='', flush=True)
        with open(os.path.join(output_dir, filename), 'w',
                  encoding='utf-8') as x:
            x.write(data['lrc']['lyric'])
            print('Done.')
예제 #9
0
파일: extractor.py 프로젝트: virsystem/Lulu
    def p_i(self, stream_id):
        if stream_id in self.streams:
            stream = self.streams[stream_id]
        else:
            stream = self.dash_streams[stream_id]

        maybe_print("    - title:         %s" % self.title)
        print("       size:         {} MiB ({} bytes)".format(
            round(stream['size'] / 1048576, 1), stream['size']))
        print("        url:         %s" % self.url)
        print()
예제 #10
0
파일: extractor.py 프로젝트: virsystem/Lulu
    def download(self, **kwargs):
        if 'json_output' in kwargs and kwargs['json_output']:
            json_output.output(self)
        elif 'info_only' in kwargs and kwargs['info_only']:
            if 'stream_id' in kwargs and kwargs['stream_id']:
                # Display the stream
                stream_id = kwargs['stream_id']
                if 'index' not in kwargs:
                    self.p(stream_id)
                else:
                    self.p_i(stream_id)
            else:
                # Display all available streams
                if 'index' not in kwargs:
                    self.p([])
                else:
                    stream_id = self.streams_sorted[0]['id'] \
                        if 'id' in self.streams_sorted[0] \
                        else self.streams_sorted[0]['itag']
                    self.p_i(stream_id)

        else:
            if 'stream_id' in kwargs and kwargs['stream_id']:
                # Download the stream
                stream_id = kwargs['stream_id']
            else:
                # Download stream with the best quality
                stream_id = self.streams_sorted[0]['id'] \
                    if 'id' in self.streams_sorted[0] \
                    else self.streams_sorted[0]['itag']

            if 'index' not in kwargs:
                self.p(stream_id)
            else:
                self.p_i(stream_id)

            if stream_id in self.streams:
                urls = self.streams[stream_id]['src']
                ext = self.streams[stream_id]['container']
                total_size = self.streams[stream_id]['size']
            else:
                urls = self.dash_streams[stream_id]['src']
                ext = self.dash_streams[stream_id]['container']
                total_size = self.dash_streams[stream_id]['size']

            if not urls:
                log.wtf('[Failed] Cannot extract video source.')

            if ext == 'm3u8':
                ffmpeg_kwargs = {}
                if 'iqiyi' in self.name:
                    # ffmpeg_kwargs['override'] = True
                    # ffmpeg_kwargs['params'] = {
                    #     '-c:a': 'copy', '-bsf:a': 'aac_adtstoasc'
                    # }
                    m3u8_urls = general_m3u8_extractor(urls[0])
                    # FIXME(iawia002): 如果要计算大小的话需要消耗太多时间
                    if len(m3u8_urls) <= 100:
                        size = urls_size(m3u8_urls)
                    else:
                        size = float('inf')
                    download_urls(m3u8_urls, self.title, 'mp4', size, **kwargs)
                else:
                    download_url_ffmpeg(urls[0],
                                        self.title,
                                        'mp4',
                                        output_dir=kwargs['output_dir'],
                                        merge=kwargs['merge'],
                                        stream=False,
                                        **ffmpeg_kwargs)
            else:
                headers = copy(config.FAKE_HEADERS)
                if self.ua is not None:
                    headers['User-Agent'] = self.ua
                if self.referer is not None:
                    headers['Referer'] = self.referer
                download_urls(urls,
                              self.title,
                              ext,
                              total_size,
                              headers=headers,
                              output_dir=kwargs['output_dir'],
                              merge=kwargs['merge'],
                              av=stream_id in self.dash_streams)
            if 'caption' not in kwargs or not kwargs['caption']:
                print('Skipping captions or danmuku.')
                return
            for lang in self.caption_tracks:
                filename = '%s.%s.srt' % (get_filename(self.title), lang)
                print('Saving %s ... ' % filename, end="", flush=True)
                srt = self.caption_tracks[lang]
                with open(os.path.join(kwargs['output_dir'], filename),
                          'w',
                          encoding='utf-8') as x:
                    x.write(srt)
                print('Done.')
            if self.danmuku is not None and not dry_run:
                filename = '{}.cmt.xml'.format(get_filename(self.title))
                print('Downloading {} ...\n'.format(filename))
                with open(os.path.join(kwargs['output_dir'], filename),
                          'w',
                          encoding='utf8') as fp:
                    fp.write(self.danmuku)

        keep_obj = kwargs.get('keep_obj', False)
        if not keep_obj:
            self.__init__()
예제 #11
0
파일: extractor.py 프로젝트: virsystem/Lulu
 def p_playlist(self, stream_id=None):
     maybe_print("site:                %s" % self.__class__.name)
     print("playlist:            %s" % self.title)
     print("videos:")
예제 #12
0
파일: extractor.py 프로젝트: virsystem/Lulu
    def p(self, stream_id=None):
        maybe_print("site:                %s" % self.__class__.name)
        maybe_print("title:               %s" % self.title)
        if stream_id:
            # Print the stream
            print("stream:")
            self.p_stream(stream_id)

        elif stream_id is None:
            # Print stream with best quality
            print("stream:              # Best quality")
            stream_id = self.streams_sorted[0]['id'] \
                if 'id' in self.streams_sorted[0] \
                else self.streams_sorted[0]['itag']
            self.p_stream(stream_id)

        elif stream_id == []:
            print("streams:             # Available quality and codecs")
            # Print DASH streams
            if self.dash_streams:
                print("    [ DASH ] %s" % ('_' * 36))
                itags = sorted(self.dash_streams,
                               key=lambda i: -self.dash_streams[i]['size'])
                for stream in itags:
                    self.p_stream(stream)
            # Print all other available streams
            print("    [ DEFAULT ] %s" % ('_' * 33))
            for stream in self.streams_sorted:
                self.p_stream(stream['id'] if 'id' in
                              stream else stream['itag'])

        if self.audiolang:
            print("audio-languages:")
            for i in self.audiolang:
                print("    - lang:          {}".format(i['lang']))
                print("      download-url:  {}\n".format(i['url']))
예제 #13
0
파일: extractor.py 프로젝트: virsystem/Lulu
    def p_stream(self, stream_id):
        if stream_id in self.streams:
            stream = self.streams[stream_id]
        else:
            stream = self.dash_streams[stream_id]

        if 'itag' in stream:
            print("    - itag:          %s" %
                  log.sprint(stream_id, log.NEGATIVE))
        else:
            print("    - format:        %s" %
                  log.sprint(stream_id, log.NEGATIVE))

        if 'container' in stream:
            print("      container:     %s" % stream['container'])

        if 'video_profile' in stream:
            maybe_print("      video-profile: %s" % stream['video_profile'])

        if 'quality' in stream:
            print("      quality:       %s" % stream['quality'])

        if 'size' in stream and stream['container'].lower() != 'm3u8':
            if stream['size'] != float('inf') and stream['size'] != 0:
                print("      size:          {} MiB ({} bytes)".format(
                    round(stream['size'] / 1048576, 1), stream['size']))

        if 'm3u8_url' in stream:
            print("      m3u8_url:      {}".format(stream['m3u8_url']))

        if 'itag' in stream:
            print(
                "    # download-with: %s" %
                log.sprint("lulu --itag=%s [URL]" % stream_id, log.UNDERLINE))
        else:
            print("    # download-with: %s" % log.sprint(
                "lulu --format=%s [URL]" % stream_id, log.UNDERLINE))

        print()
예제 #14
0
파일: extractor.py 프로젝트: youmuyou/Lulu
    def download(self, **kwargs):
        if 'json_output' in kwargs and kwargs['json_output']:
            json_output.output(self)
        elif 'info_only' in kwargs and kwargs['info_only']:
            if 'stream_id' in kwargs and kwargs['stream_id']:
                # Display the stream
                stream_id = kwargs['stream_id']
                if 'index' not in kwargs:
                    self.p(stream_id)
                else:
                    self.p_i(stream_id)
            else:
                # Display all available streams
                if 'index' not in kwargs:
                    self.p([])
                else:
                    stream_id = self.streams_sorted[0]['id'] \
                        if 'id' in self.streams_sorted[0] \
                        else self.streams_sorted[0]['itag']
                    self.p_i(stream_id)

        else:
            if 'stream_id' in kwargs and kwargs['stream_id']:
                # Download the stream
                stream_id = kwargs['stream_id']
            else:
                # Download stream with the best quality
                stream_id = self.streams_sorted[0]['id'] \
                    if 'id' in self.streams_sorted[0] \
                    else self.streams_sorted[0]['itag']

            if 'index' not in kwargs:
                self.p(stream_id)
            else:
                self.p_i(stream_id)

            if stream_id in self.streams:
                urls = self.streams[stream_id]['src']
                ext = self.streams[stream_id]['container']
                total_size = self.streams[stream_id]['size']
            else:
                urls = self.dash_streams[stream_id]['src']
                ext = self.dash_streams[stream_id]['container']
                total_size = self.dash_streams[stream_id]['size']

            if ext == 'm3u8':
                ext = 'mp4'

            if not urls:
                log.wtf('[Failed] Cannot extract video source.')
            # For legacy main()
            headers = copy(config.FAKE_HEADERS)
            if self.ua is not None:
                headers['User-Agent'] = self.ua
            if self.referer is not None:
                headers['Referer'] = self.referer
            download_urls(
                urls,
                self.title,
                ext,
                total_size,
                headers=headers,
                output_dir=kwargs['output_dir'],
                merge=kwargs['merge'],
                av=stream_id in self.dash_streams
            )
            if 'caption' not in kwargs or not kwargs['caption']:
                print('Skipping captions or danmuku.')
                return
            for lang in self.caption_tracks:
                filename = '%s.%s.srt' % (get_filename(self.title), lang)
                print('Saving %s ... ' % filename, end="", flush=True)
                srt = self.caption_tracks[lang]
                with open(
                    os.path.join(kwargs['output_dir'], filename),
                    'w',
                    encoding='utf-8'
                ) as x:
                    x.write(srt)
                print('Done.')
            if self.danmuku is not None and not dry_run:
                filename = '{}.cmt.xml'.format(get_filename(self.title))
                print('Downloading {} ...\n'.format(filename))
                with open(
                    os.path.join(kwargs['output_dir'], filename),
                    'w',
                    encoding='utf8'
                ) as fp:
                    fp.write(self.danmuku)

            # For main_dev()
            # download_urls(
            #     urls, self.title, self.streams[stream_id]['container'],
            #     self.streams[stream_id]['size']
            # )
        keep_obj = kwargs.get('keep_obj', False)
        if not keep_obj:
            self.__init__()
예제 #15
0
    def download(self, **kwargs):
        """Override the original one
        Ugly ugly dirty hack
        """
        if 'json_output' in kwargs and kwargs['json_output']:
            json_output.output(self)
        elif 'info_only' in kwargs and kwargs['info_only']:
            if 'stream_id' in kwargs and kwargs['stream_id']:
                # Display the stream
                stream_id = kwargs['stream_id']
                if 'index' not in kwargs:
                    self.p(stream_id)
                else:
                    self.p_i(stream_id)
            else:
                # Display all available streams
                if 'index' not in kwargs:
                    self.p([])
                else:
                    stream_id = self.streams_sorted[0]['id'] \
                        if 'id' in self.streams_sorted[0] \
                        else self.streams_sorted[0]['itag']
                    self.p_i(stream_id)

        else:
            if 'stream_id' in kwargs and kwargs['stream_id']:
                # Download the stream
                stream_id = kwargs['stream_id']
            else:
                # Download stream with the best quality
                stream_id = self.streams_sorted[0]['id'] \
                    if 'id' in self.streams_sorted[0] \
                    else self.streams_sorted[0]['itag']

            if 'index' not in kwargs:
                self.p(stream_id)
            else:
                self.p_i(stream_id)

            if stream_id in self.streams:
                urls = self.streams[stream_id]['src']
                # ext = self.streams[stream_id]['container']
                # total_size = self.streams[stream_id]['size']
            else:
                urls = self.dash_streams[stream_id]['src']
                # ext = self.dash_streams[stream_id]['container']
                # total_size = self.dash_streams[stream_id]['size']

            if not urls:
                log.wtf('[Failed] Cannot extract video source.')

            # Here's the change!
            download_url_ffmpeg(urls[0],
                                self.title,
                                'mp4',
                                output_dir=kwargs['output_dir'],
                                merge=kwargs['merge'],
                                stream=False)

            if not kwargs['caption']:
                print('Skipping captions.')
                return
            for lang in self.caption_tracks:
                filename = '{}.{}.srt'.format(get_filename(self.title), lang)
                print('Saving {} ... '.format(filename), end='', flush=True)
                srt = self.caption_tracks[lang]
                with open(os.path.join(kwargs['output_dir'], filename),
                          'w',
                          encoding='utf-8') as x:
                    x.write(srt)
                print('Done.')