zoukankan      html  css  js  c++  java
  • 在win10电脑上设置默认编码为UTF-8,无法正常播放U盘中的音乐,我写了一个播放器解决

    背景

    我打开了win10系统里的“beta版:使用Unicode UTF-8 提供全球语言支持”,

    其副作用之一就是播放U盘中的音乐时会出现错误,无法播放。

    如图:

    播放错误时的截图

    在U盘端上只能正常播放名称全由ascii字符组成的文件。

    我的解决办法是将音乐文件复制到本地,再播放

    实现播放器

    首先使用os.listdir获取文件列表,再从中获取.mp3文件。

    如下:

    import os
    def get_mp3_files(path = r'D:/audios'):
        '''
        获取.mp3文件,path是音乐文件夹的路径。
        '''
        return [f'{path}//{i}' for i in os.listdir(path)
                if i.endswith('.mp3')]
    

    接下来实现播放器的核心,也就是播放音乐。

    因为我修改了设置,需要先将文件复制到本地,再播放。

    这里我使用shutil.copy进行复制,pygame.mixer实现播放。

    import shutil
    from pygame import mixer
    
    mixer.init()
    
    def play_file(path):
        '''
        播放.mp3音乐文件。
        '''
        shutil.copy(path, "_.mp3")
        #将 path 对应的文件复制到工作区,命名为“_.mp3”。
    
        mixer.music.load('_.mp3')
        #加载文件。
    
        mixer.music.play()
        #播放文件,非阻塞。
    

    最后,用tkinter实现图形化界面。

    import tkinter as tk
    
    def tk_show(path=r'D:/audios'):
        '''
        '''
        mp3_list = get_mp3_files(path)
        #含有指定文件夹的所有mp3文件列表,使用的是我刚才定义的函数。
    
        from random import choice
        from collections import deque
        #`deque`是“双向队列”,将用于储存播放记录,利用其自动删除过量元素的属性。
    
        music_log = deque(maxlen = 10)
        #记录十首播放过的音乐(含正在播放的)。
    
        root = tk.Tk()
        shower = tk.Label(root, text='Empty!')
    
        def button_play(music_name = None):
            '''
            随机播放一首音乐,并将音乐名写入文本框'shower'。
            如果'music_name'为'None',
            则在'mp3_list'里随机获取一个,写入播放记录并播放。
            否则只播放'music_name,不写入记录表。
            '''
            if music_name is None:
                music_name = choice(mp3_list)
                #随机获取一个音乐文件名。
    
                while music_name in music_log:
                #如果获取的音乐在近期被播放过,也就是在记录表中,
                #就再次重新随机获取。
    
                    music_name = choice(mp3_list)
                else:
                    music_log.append(music_name)
                    #把将要播放的音乐写入记录表。
                    #如果表中已有maxlen(前面设置为10)个元素,则第一个元素会被删除。   
                    #所以记录表只会记录最后十首音乐。
            
            shower.config(text=os.path.basename(music_name))
            #将歌名写入文本框。`os.path.basename`返回文件名。
    
            play_file(music_name)
            button_p.config(text='display', command=button_display)
            #重新设置按钮的显示文本、命令。
        
        def button_display():
            '''
            结束播放。并将'Empty!'文本框'shower'。
            '''
            mixer.music.stop()
            #结束正在播放的音乐。
    
            mixer.music.load('_a_file_to_unload.mp3')
            #将底层播放器加载到另一个文件上,以释放刚才在播放的'_.mp3',
            #否则在复制文件时会出错。
    
            button_p.config(text='play', command=button_play)
            #重新设置'button_p'。
    
            shower.config(text='Empty!')
        
        def button_again():
            '''
            重播。
            '''
            button_display()
            #先停止播放。
    
            button_play(music_log[-1])
        
        def button_last():
            '''
            播放上一首。
            '''
            button_display()
            #先停止播放。
    
            music_log.pop()
            #删去最后的播放记录,也就是正在播放的。
    
            button_play(music_log[-1])
            #提供现在的最后一条播放记录。
        
        buttoms = tk.Frame(root)
        #操作按钮都挂载在它上面。
    
        button_p = tk.Button(buttoms, text='PLAY', command=button_play)
        button_p.pack(side='left')
    
        tk.Button(buttoms, text='play last one', command=button_last)
                  .pack(side='left')
        tk.Button(buttoms, text='again', command=button_again)
            .pack(side='left')
        
        shower.pack()
        buttoms.pack()
        
        return root
    

    写一个main函数:

    def main(path=r'D:/audios'):
        tk_show(path).mainloop()
    

    效果图:

    效果图

    闲谈

    如果不在结束播放时,将'mixer.music'挂载在别的文件上,
    覆盖刚才播放的文件会出现“PermissionError”。
    当时我真是一脸懵逼,在网上搜了半天也没有找到。最后尝试着解决的。

  • 相关阅读:
    Struts2 拦截器(interceptor) 与 模型驱动3中传值方式
    Struts2 OGNL表达式
    ThreadLocal 是什么
    struts2的值栈(重点) 值栈是一个存储数据的内存结构 本质是一个接口 它的实现类OgnlValueStack
    Struts2 普通的java类 (Action)与Servlet通信 主要对象那个ServletActionContext 与 ActionContext对象来获取servlet中request对象和response对象
    struts2是多例的
    Django中一个项目里怎么使用两个数据库
    MYSQL中的锁
    详解Linux中文乱码问题终极解决方法
    Docker-compose up时报错:
  • 原文地址:https://www.cnblogs.com/tobe-goodlearner/p/13026408.html
Copyright © 2011-2022 走看看