main.py 文件源码

python
阅读 27 收藏 0 点赞 0 评论 0

项目:jsrlive-cli 作者: pqlime 项目源码 文件源码
def play_song(name, url):
    """
    Function that plays a song in a new thread

    Args:
        name (str): Name to display
        url (str): URL to fetch the mp3 from
    """
    global current_song
    global playback_progress

    current_song = 'Loading...'  # Set the song name to 'Loading...' to notify the user
    playback_progress = 0

    wav = download_mp3_to_wav(url)  # Download the mp3 file as a wav from jetsetradio.live
    if not wav:  # If there's no wav returned, don't play it
        return

    current_song = name  # Set the song name to the new song

    pa = pyaudio.PyAudio()  # Main class of pyAudio; contains the open() function we need for an audio stream

    # Opens an audio stream on the default output device.
    # Explained: We're using 1/2th the framerate because we're going from Int16 to Float32; this change
    # requires us to get twice the amount of data, hence leaving us with twice the amount of bytes.
    # We convert from Int16 to Float32 to prevent byte overflow, which results in garbled (and scary) static.
    audio_stream = pa.open(wav.getframerate() // 2, wav.getnchannels(), pyaudio.paFloat32, output=True)
    audio_stream.start_stream()

    buffer_size = audio_stream._frames_per_buffer  # The amount of int16's to read per frame

    while True:
        data = wav.readframes(buffer_size * 2)  # Read data from wav
        if isinstance(data, str):  # Check typing to prevent errors
            data = data.encode('utf-8')

        # Take each byte, divide by 0x7FFF to get a float, and then multiply that by the volume constant
        data = struct.pack('f' * (len(data) // 2), *list(map(lambda b: b / 65535 * (volume / 9),
                           struct.unpack('H' * (len(data) // 2), data))))
        playback_progress = wav.tell() / wav.getnframes()  # Set percent of song played
        audio_stream.write(data)  # Write raw data to speakers

        if len(data) // 2 < buffer_size:  # If we're out of data, exit the loop
            break
        if current_song != name:  # If the song changed halfway through, stop the stream
            break

    audio_stream.stop_stream()

    del audio_stream  # Cleanup unused variables
    del pa
    del wav


# Main code
评论列表
文章目录


问题


面经


文章

微信
公众号

扫码关注公众号