コード例 #1
0
def stream():
    url = request.args.get('url')
    stream_settings = {
        'lo': 'webm[abr<=64]/webm[abr<=80]/m4a[abr<=64]/[abr<=96]/m4a',
        'md': 'webm[abr>=64][abr<=96]/[abr>=64][abr<=96]/webm[abr>=96][abr<=128]/webm/m4a',
        'hi': 'webm/m4a'
    }
    try:
        req = decode_data(get_key(), url)
        vid_id = req['id']
        quality = req.get('quality', 'md')
        url = get_or_create_video_download_link(
            vid_id,
            stream_settings[quality],
            get_download_link_youtube
        )
    except Exception as e:
        logger.info(traceback.format_exc())
        return make_error_response(msg=str(e), endpoint='api/v1/stream')
    return jsonify(
        status=200,
        url=url_for(
            'stream_handler',
            url=encode_data(get_key(), url=url)
        )
    )
コード例 #2
0
def get_link():
    """
    Uses youtube-dl to fetch the direct link
    """
    try:
        url = request.args.get('url')

        data = decode_data(get_key(), url)
        vid_id = data['id']
        title = data['title']
        retval = get_download_link_youtube(vid_id, 'm4a/bestaudio')
        if not LOCAL:
            retval = encode_data(get_key(),
                                 id=vid_id,
                                 title=title,
                                 url=retval,
                                 length=data['length'])
            retval = url_for('download_file', url=retval)

        ret_dict = {
            'status': 200,
            'requestLocation': '/api/v1/g',
            'url': retval
        }
        return jsonify(ret_dict)
    except Exception as e:
        logger.info(traceback.format_exc())
        return make_error_response(msg=str(e), endpoint='/api/v1/g')
コード例 #3
0
def stream_handler():
    url = request.args.get('url')

    try:
        url = decode_data(get_key(), url)['url']
    except Exception:
        return 'Bad URL', 400

    mime = 'audio/mp4'
    if url.find('mime=audio%2Fwebm') > -1:
        mime = 'audio/webm'

    range_header = request.headers.get('Range', None)
    if range_header:
        from_bytes, until_bytes = range_header.replace('bytes=', '').split('-')
        if not until_bytes:
            until_bytes = int(from_bytes) + int(
                1024 * 1024 * 1)  # 1MB * 1 = 1MB
        headers = {'Range': 'bytes=%s-%s' % (from_bytes, until_bytes)}
        r = requests.get(url, headers=headers)
        data = r.content
        rv = Response(data, 206, mimetype=mime, direct_passthrough=True)
        rv.headers.add('Content-Range', r.headers.get('Content-Range'))
        return rv

    r = requests.get(url, stream=True)

    return Response(generate_data(r), mimetype=mime)
コード例 #4
0
ファイル: api_v1.py プロジェクト: Monal5031/anyaudio-server
def suggest_songs():

    try:
        url = request.args.get('url')

        decoded_data = decode_data(get_key(), url)

        vid_id = decoded_data["id"]

        vids = get_suggestions(vid_id)

        count = len(vids)

        return jsonify(
            {
                "status": 200,
                "request_location": "/api/v1/suggest",
                "metadate": {
                    "count": count
                },
                "results": vids
            }
        )

    except Exception as e:
        return make_error_response(msg=str(e), endpoint='/api/v1/suggest')
コード例 #5
0
def stream_v2():
    url = request.args.get('url')
    try:
        vid_id = decode_data(get_key(), url)['id']
        url = get_stream(vid_id)
        return jsonify(status=200, url=url)
    except Exception as e:
        return make_error_response(msg=str(e), endpoint='api/v2/stream')
コード例 #6
0
def get_link_v2():
    url = request.args.get('url')
    try:
        data = decode_data(get_key(), url)
        vid_id = data['id']
        retval = get_download(vid_id)
        return jsonify(status=200, url=retval)
    except Exception as e:
        return make_error_response(msg=str(e), endpoint='/api/v2/g')
コード例 #7
0
ファイル: api_v1.py プロジェクト: Monal5031/anyaudio-server
def download_file():
    """
    Download the file from the server.
    First downloads the file on the server using wget and then converts it using ffmpeg
    """
    try:
        url = request.args.get('url')
        download_format = request.args.get('format', 'm4a')
        try:
            abr = int(request.args.get('bitrate', '128'))
            abr = abr if abr >= 64 else 128  # Minimum bitrate is 128
        except ValueError:
            abr = 128
        download_album_art = request.args.get('cover', 'false').lower()
        # decode info from url
        data = decode_data(get_key(), url)
        vid_id = data['id']
        url = data['url']
        filename = get_filename_from_title(data['title'], ext='')
        m4a_path = 'static/%s.m4a' % vid_id
        mp3_path = 'static/%s.mp3' % vid_id
        # ^^ vid_id regex is filename friendly [a-zA-Z0-9_-]{11}
        # download and convert
        command = 'curl -o %s %s' % (m4a_path, url)
        check_output(command.split())
        if download_album_art == 'true':
            add_cover(m4a_path, vid_id)
        if download_format == 'mp3':
            if extends_length(data['length'], 20 * 60):  # sound more than 20 mins
                raise Exception()
            command = get_ffmpeg_path()
            command += ' -i %s -acodec libmp3lame -ab %sk %s -y' % (m4a_path, abr, mp3_path)
            call(command, shell=True)  # shell=True only works, return ret_code
            with open(mp3_path, 'r') as f:
                data = f.read()
            content_type = 'audio/mpeg'  # or audio/mpeg3'
            filename += '.mp3'
        else:
            with open(m4a_path, 'r') as f:
                data = f.read()
            content_type = 'audio/mp4'
            filename += '.m4a'
        response = make_response(data)
        # set headers
        # http://stackoverflow.com/questions/93551/how-to-encode-the-filename-
        response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
        response.headers['Content-Type'] = content_type
        response.headers['Content-Length'] = str(len(data))
        # remove files
        delete_file(m4a_path)
        delete_file(mp3_path)
        # stream
        return response
    except Exception as e:
        logger.info('Error %s' % str(e))
        logger.info(traceback.format_exc())
        return 'Bad things have happened', 500
コード例 #8
0
def get_log_page():
    """
    View application logs
    """
    user_key = request.args.get('key')

    if not user_key or user_key != get_key():
        return render_template('/unauthorized.html')

    try:
        offset = int(request.args.get('offset', '0'))
        if offset < 0:
            offset = 0
    except Exception:
        offset = 0

    try:
        number = int(request.args.get('number', '10'))
        if number < 1:
            number = 1
    except Exception:
        number = 0

    result = get_api_log(number, offset)

    if offset - number < 0:
        prev_link = None
    else:
        prev_link = '/logs?key={0}&number={1}&offset={2}'.format(
            user_key, number, offset - number)

    next_link = '/logs?key={0}&number={1}&offset={2}'.format(
        user_key, number, offset + number)

    day_path = result['day_path']
    day_sum = sum([x[1] for x in day_path])

    month_path = result['month_path']
    month_sum = sum([x[1] for x in month_path])

    all_path = result['all_path']
    all_sum = sum([x[1] for x in all_path])

    return render_template('/log_page.html',
                           logs=result['logs'],
                           number=number,
                           offset=offset,
                           prev_link=prev_link,
                           next_link=next_link,
                           day_path=day_path,
                           day_sum=day_sum,
                           month_path=month_path,
                           month_sum=month_sum,
                           all_path=result['all_path'],
                           all_sum=all_sum,
                           popular_queries=result['popular_query'])
コード例 #9
0
def get_video_attrs(html):
    """
    get video attributes from html
    """
    result = {}
    # get video id and description
    regex = 'yt\-lockup\-title.*?href.*?watch\?v\=(.*?[^\"]+)'
    regex += '.*? title\=\"(.*?[^\"]+)'
    temp = re.findall(regex, html)
    if len(temp) and len(temp[0]) == 2:
        result['id'] = temp[0][0]
        result['title'] = html_unescape(temp[0][1])
    # length
    length_regex = 'video\-time.*?\>([^\<]+)'
    temp = re.findall(length_regex, html)
    if len(temp) > 0:
        result['length'] = temp[0].strip()
    # uploader
    upl_regex = 'yt\-lockup\-byline.*?\>.*?\>([^\<]+)'
    temp = re.findall(upl_regex, html)
    if len(temp) > 0:
        result['uploader'] = temp[0].strip()
    # time ago
    time_regex = 'yt\-lockup\-meta\-info.*?\>.*?\>([^\<]+).*?([0-9\,]+)'
    temp = re.findall(time_regex, html)
    if len(temp) and len(temp[0]) == 2:
        result['time'] = temp[0][0]
        result['views'] = temp[0][1]
    # thumbnail
    if 'id' in result:
        thumb = 'https://img.youtube.com/vi/%s/0.jpg' % result['id']
        result['thumb'] = thumb
    else:
        return None
    # Description
    desc_regex = 'yt-lockup-description.*?>(.*?)<'
    temp = re.findall(desc_regex, html)
    if len(temp) > 0:
        result['description'] = temp[0]
    else:
        result['description'] = ''

    # check if all items present. If not present, usually some problem in parsing
    if len(result) != 8:
        return None
    # return
    result['get_url'] = '/g?url=' + encode_data(
        get_key(),
        id=result['id'],
        title=result['title'],
        length=result['length']).decode('utf-8')
    result['stream_url'] = result['get_url'].replace('/g?', '/stream?', 1)
    return result
コード例 #10
0
def download_file():
    """
    Download the file from the server.
    First downloads the file on the server using wget and then converts it using ffmpeg
    """
    try:
        url = request.args.get('url')
        # decode info from url
        data = decode_data(get_key(), url)
        vid_id = data['id']
        url = data['url']
        filename = get_filename_from_title(data['title'], ext='')
        m4a_path = 'static/%s.m4a' % vid_id
        # ^^ vid_id regex is filename friendly [a-zA-Z0-9_-]{11}

        # Handle partial request
        range_header = request.headers.get('Range', None)
        if range_header:
            from_bytes, until_bytes = range_header.replace('bytes=',
                                                           '').split('-')
            if not until_bytes:
                until_bytes = int(from_bytes) + int(
                    1024 * 1024 * 1)  # 1MB * 1 = 1MB
            headers = {'Range': 'bytes=%s-%s' % (from_bytes, until_bytes)}
            resp = requests.get(url, headers=headers, stream=True)
            rv = Response(generate_data(resp),
                          206,
                          mimetype='audio/mp4',
                          direct_passthrough=True)
            rv.headers.add('Content-Range', resp.headers.get('Content-Range'))
            rv.headers.add('Content-Disposition',
                           'attachment; filename="%s"' % filename)
            rv.headers.add('Content-Length', resp.headers['Content-Length'])
            return rv

        resp = requests.get(url, stream=True)
        filename += '.m4a'
        response = Response(generate_data(resp), mimetype='audio/mp4')
        # set headers
        # http://stackoverflow.com/questions/93551/how-to-encode-the-filename-
        response.headers.add('Content-Disposition',
                             'attachment; filename="%s"' % filename)
        response.headers.add('Content-Length', resp.headers['Content-Length'])
        return response
    except Exception as e:
        logger.info('Error %s' % str(e))
        logger.info(traceback.format_exc())
        return 'Bad things have happened', 500
コード例 #11
0
def get_suggestions(vid_id, get_url_prefix='/api/v1'):
    url = "https://www.youtube.com/watch?v=" + vid_id
    raw_html = open_page(url)

    area_of_concern = ' '.join(
        area_of_concern_regex.findall(raw_html, re.DOTALL))

    videos_html = videos_html_regex.findall(area_of_concern, re.DOTALL)

    ret_list = []
    for video in videos_html:
        try:
            _id = single_video_regex['id'].findall(video)[0]
            if '&amp;list=' in _id:
                continue
            title = single_video_regex['title'].findall(video)[0]
            duration = single_video_regex['duration'].findall(video)[0]
            uploader = single_video_regex['uploader'].findall(video)[0]
            views = single_video_regex['views'].findall(video)[0]
            encoded_data = encode_data(get_key(),
                                       id=_id,
                                       title=title,
                                       length=duration).decode('utf-8')
            get_url = get_url_prefix + '/g?url=' + encoded_data
            stream_url = get_url.replace('/g?', '/stream?', 1)
            suggest_url = get_url.replace('/g?', '/suggest?', 1)

            ret_list.append({
                "id": _id,
                "title": html_unescape(title),
                "length": duration,
                "uploader": uploader,
                "thumb": 'https://img.youtube.com/vi/%s/0.jpg' % _id,
                "get_url": get_url,
                "stream_url": stream_url,
                "views": views,
                "suggest_url": suggest_url
            })
        except Exception:
            print('Error while getting suggestion at video \n' + video)
            traceback.print_exc()

    return ret_list
コード例 #12
0
ファイル: api_v1.py プロジェクト: Monal5031/anyaudio-server
def stream_handler():
    url = request.args.get('url')

    try:
        url = decode_data(get_key(), url)['url']
    except Exception:
        return 'Bad URL', 400

    def generate_data():
        r = requests.get(url, stream=True)
        logger.info('Streaming.. %s (%s bytes)' % (
            r.headers.get('content-type'),
            r.headers.get('content-length')
        ))
        for data_chunk in r.iter_content(chunk_size=2048):
            yield data_chunk

    mime = 'audio/mp4'
    if url.find('mime=audio%2Fwebm') > -1:
        mime = 'audio/webm'
    return Response(generate_data(), mimetype=mime)
コード例 #13
0
def get_trending_videos(html):
    """
    Get trending youtube videos from html
    """
    regex = '<tr.*?data-video-id="(.*?)".*?src="(.*?)".*?<a cl.*?>(.*?)</a>.*?by.*?>(.*?)</a>.*?<span .*?>(.*?)</'

    raw_results = re.findall(
        regex,
        html,
        re.DOTALL
    )[:int(environ.get('PLAYLIST_VIDEOS_LIMIT', 100))]

    vids = []
    for raw_result in raw_results:
        try:
            url = 'https://www.youtube.com/watch?v=' + raw_result[0]
            html = open_page(url)
            vids.append(
                {
                    'id': raw_result[0],
                    'thumb': 'https://img.youtube.com/vi/{0}/0.jpg'.format(raw_result[0]),
                    'title': html_unescape(raw_result[2].strip()),
                    'uploader': raw_result[3],
                    'length': raw_result[4],
                    'views': get_views(html),
                    'get_url': encode_data(
                        get_key(), id=raw_result[0],
                        title=raw_result[2].strip(), length=raw_result[4]
                    ),
                    'description': html_unescape(get_description(html))
                }
            )
        except Exception as e:
            logger.info(
                'Getting trending video failed. Message: %s, Video: %s' % (
                    str(e), raw_result[0]
                )
            )
    return vids