程序是事件驱动的,写博客是什么驱动的?事件? 时间?no,我承认我很懒,甚至不愿意记录总结。哪是什么驱动的? 对! 问题驱动的。遇到了问题解决了问题突然想起来搬到blog上,让遇到相同问题的可以参考下。

问题所在

我用的Electronic WeChat,当朋友发送文字、图片、甚至视频的时候都可以打开(Audio无法收听,因为电脑无外设音响/喇叭)。但发来的语音就扯蛋了,只能通过手机听,甚至不能转发。

python png格式的数值 python png转jpg_v9

但是发现可以通过开发者工具看到http语音文件的请求地址。

python png格式的数值 python png转jpg_v9_02

直接复制url在浏览器中打开没有任何响应?难道是Referer与Cookie有判断。果然!只有在登陆的浏览器中可以,不信你可以直接在浏览器中打开web微信尝试操作,Electronic WeChat 只有一个tab。open link in new tab 其实就跳转到浏览器了。然而开发者工具带了一个骚操作,那就是“Copy Response”

python png格式的数值 python png转jpg_v9_03

copy response的数据为base64内容:



data:audio/mp3;base64,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



 

所以将base64转换为对应的mp3格式不就可以播放了吗?.......

 base64

Python的base64函数是内置函数,是一种用64个字符来表示任意二进制数据的方法。用记事本打开exejpgpdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的文本处理软件能处理二进制数据,就需要一个二进制到字符串的转换方法。Base64是一种最常见的二进制编码方法。

廖雪峰老师对base64的介绍

 

 base64对文件的编码解码

对文件的编码就是读取文件内容,encode为base64,对文件的解码就是将base64字符串转换为文件二进制。

  • 编码使用 base64.b64encode()
  • 解码使用 base64.b64decode()

读取文件我们可以用with open as 也可以直接open,区别是with智能关闭文件,open要手动close文件。参考:

上代码:



def ToBase64(file, txt):
    with open(file, 'rb') as fileObj:
        image_data = fileObj.read()
        base64_data = base64.b64encode(image_data)
        fout = open(txt, 'w')
        fout.write(base64_data.decode())
        fout.close()


def ToFile(txt, file):
    with open(txt, 'r') as fileObj:
        base64_data = fileObj.read()
        ori_image_data = base64.b64decode(base64_data)
        fout = open(file, 'wb')
        fout.write(ori_image_data)
        fout.close()

ToBase64("./desk.jpg",'desk_base64.txt')  # 文件转换为base64
ToFile("./desk_base64.txt",'desk_cp_by_base64.jpg')  # base64编码转换为二进制文件



 

pyqt的GUI外衣

想转换命令行就如上,但是操作不方便,可以给base64的代码穿一个GUI外衣,使用pyqt方便的不得了!



# -*- coding: UTF8 -*-
import io, shutil, sys, os
from PyQt5.QtWidgets import *
from PyQt5 import QtGui
import base64


class MainWidgetUI(QDialog):
    def __init__(self):
        super().__init__()
        self.setFixedSize(250, 200)  # PyQT禁止调整窗口大小
        self.setWindowTitle('文件base64编码互转')
        self.setWindowIcon(QtGui.QIcon("favicon.ico"))

        Layout = QVBoxLayout()
        self.pushButton1 = QPushButton("To base64")
        self.pushButton2 = QPushButton("To file")
        Layout.addWidget(self.pushButton1)  # addWidget 添加一个挂件
        Layout.addSpacing(100)  # 添加一个100px的空间距离 且不带弹性
        Layout.addWidget(self.pushButton2)
        self.setLayout(Layout)  # setLayout设置 QVBoxLayout()垂直 与QHBoxLayout() 水平布局, 查看布局请移步CURL-api.py
        # pushButton1点击按钮
        self.pushButton1.clicked.connect(self.Tobase64)
        # pushButton2点击按钮
        self.pushButton2.clicked.connect(self.Tofile)

    def Tobase64(self):
        fileDict = self.selectFile()
        if fileDict:
            GlobalToBase64(fileDict['file'], fileDict['filepath'] + "/" + fileDict['shotname'] + ".txt")
            QMessageBox.information(self, '提示!', "转换成功", QMessageBox.Yes)

    def Tofile(self):
        fileDict = self.selectFile()
        if fileDict:
            # 简单判断文件是否自带Mime 文件扩展 data:audio/mp3;base64,
            fobj = open(fileDict['file'])
            contents = fobj.read()
            extensions = contents.split(',')[0].rsplit('/')[1].split(';')
            if len(extensions) == 2:  # ['mp3', 'base64'] 格式为两个
                # 生成临时文件保存base64
                tmpFile = fileDict['filepath'] + "/" + fileDict['shotname'] + ".tmp"
                tmpFileObj = open(tmpFile, 'w')
                tmpFileObj.write(contents.split(',')[1])
                tmpFileObj.close()
                GlobalToFile(tmpFile, fileDict['filepath'] + "/" + fileDict['shotname'] + "." + extensions[0])
                QMessageBox.information(self, '提示!', "转换成功", QMessageBox.Yes)
                os.remove(tmpFile)  # 删除临时文件

            else:  # 无mime
                mine, okPressed = QInputDialog.getText(self, "文件格式类型", "请输入文件格式类型:", QLineEdit.Normal,
                                                       "mp3")  # 获取输入对话框内容
                if okPressed and mine:  # 选择确认且输入文本
                    GlobalToFile(fileDict['file'], fileDict['filepath'] + "/" + fileDict['shotname'] + "." + mine)
                    QMessageBox.information(self, '提示!', "转换成功", QMessageBox.Yes)
                else:
                    return False

    def selectFile(self):
        '''
        选择文件
        '''
        # getOpenFileName  只能选择一个    getOpenFileNames  可多个选择
        file = QFileDialog.getOpenFileName(self, "请选择文件", '', "*.*")
        if file[0] == '':
            QMessageBox.warning(self, '错误提示!', "请选择文件", QMessageBox.Yes)
        else:
            (filepath, filename) = os.path.split(file[0])  # 获取文件路径,文件名
            (shotname, extension) = os.path.splitext(filename)  # 获取文件名称,文件后缀
            return {"file": file[0], "filepath": filepath, "shotname": shotname}


def GlobalToBase64(file, txt):
    with open(file, 'rb') as fileObj:
        image_data = fileObj.read()
        base64_data = base64.b64encode(image_data)
        fout = open(txt, 'w')
        fout.write(base64_data.decode())
        fout.close()


def GlobalToFile(txt, file):
    with open(txt, 'r') as fileObj:
        base64_data = fileObj.read()
        ori_image_data = base64.b64decode(base64_data)
        fout = open(file, 'wb')
        fout.write(ori_image_data)
        fout.close()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_widget = MainWidgetUI()
    main_widget.show()
    sys.exit(app.exec_())



效果:

python png格式的数值 python png转jpg_v9_04

 

python png格式的数值 python png转jpg_c/c++_05

  

python png格式的数值 python png转jpg_python_06

 

 

这样就可以把微信发送的语音文件保存下来了。猜猜上面那个 “data:audio/mp3;base64,..”说的什么玩意。