OGG conver to MP3

之前用QQ音乐下载音乐到本地来听,发现是OGG的格式,会发现有一些兼容性的问题,在有一些设备上没有兼容的软件导致听不了。我找了找,发现网络上有挺多这种开源的网站能够免费帮助你转换格式的~ 但是受限于网络,想要转换的歌曲一多,就特别慢或者就是收费了。

于是我用GPT帮我写了一个OGG2MP3.py文件,非常好用,会比网站上传再下载要很快多因为都是本地用运行,也会更安全一些,代码如下,你会用话就直接复制到本的编辑器中运行就好。然后我的Github上面有更详细的说明和使用的方法。

I used to download music using QQ Music and listen to it offline, but I noticed that the downloaded files were in OGG format, which caused compatibility issues — some devices didn’t have the right software to play them. I searched online and found quite a few open-source websites that offer free format conversion, but due to network limitations, converting multiple songs was either very slow or required payment.

So, I asked GPT to help me write a script called ogg2mp3.py, and it works really well and It’s much faster than uploading and downloading websites because it’s all running locally, and it’s a little bit more secure! You can just copy the code below into your editor and run it — if you know how to use Python, it’s super easy.
I’ve also posted a more detailed explanation on my GitHub.

Python
#!/usr/bin/env python3
import argparse
import subprocess
import sys
from pathlib import Path

def convert_file(src: Path, dst: Path, bitrate: str=None, vbr: int=None, overwrite: bool=False):
    dst.parent.mkdir(parents=True, exist_ok=True)
    if dst.exists() and not overwrite:
        print(f"Skip (exists): {dst}")
        return

    # 基本 ffmpeg 命令:输入 src,输出 dst,拷贝元数据
    cmd = ["ffmpeg", "-y" if overwrite else "-n", "-i", str(src), "-map_metadata", "0"]

    # 选择编码参数:VBR 优先,没给就用 CBR 比特率
    if vbr is not None:
        # LAME VBR 质量等级 0(最好)-9(最差)。常用 2 或 3
        cmd += ["-q:a", str(vbr)]
    elif bitrate:
        # CBR 比特率,如 192k / 256k / 320k
        cmd += ["-b:a", bitrate]
    else:
        # 默认:中等质量
        cmd += ["-q:a", "2"]

    # 强制 mp3 编码器
    cmd += ["-codec:a", "libmp3lame", str(dst)]

    print(f"Converting: {src} -> {dst}")
    try:
        subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as e:
        print(f"[ERROR] Failed to convert {src}:\n{e.stdout.decode('utf-8', errors='ignore')}", file=sys.stderr)

def is_ogg(p: Path):
    return p.suffix.lower() in {".ogg", ".oga", ".ogv"}  # .ogv 也常是 Ogg 容器

def main():
    ap = argparse.ArgumentParser(description="Convert OGG to MP3 (single file or whole directory).")
    ap.add_argument("input", type=Path, help="OGG file or a directory containing OGG files")
    ap.add_argument("-o", "--output", type=Path, default=None, help="Output file or directory")
    ap.add_argument("--bitrate", help="CBR bitrate for MP3, e.g. 192k / 256k / 320k")
    ap.add_argument("--vbr", type=int, help="VBR quality 0(best)-9(worst). Example: --vbr 2")
    ap.add_argument("--overwrite", action="store_true", help="Overwrite existing output files")
    args = ap.parse_args()

    if not args.input.exists():
        print(f"[ERROR] Input not found: {args.input}", file=sys.stderr)
        sys.exit(1)

    # 参数合法性
    if args.vbr is not None and not (0 <= args.vbr <= 9):
        print("[ERROR] --vbr must be between 0 (best) and 9 (worst).", file=sys.stderr)
        sys.exit(1)

    if args.input.is_file():
        if not is_ogg(args.input):
            print(f"[ERROR] Not an OGG file: {args.input}", file=sys.stderr)
            sys.exit(1)
        # 输出路径
        if args.output:
            out_path = args.output
            if out_path.is_dir():
                out_path = out_path / (args.input.stem + ".mp3")
        else:
            out_path = args.input.with_suffix(".mp3")

        convert_file(args.input, out_path, args.bitrate, args.vbr, args.overwrite)

    else:
        # 目录批量转换
        in_dir = args.input
        out_dir = args.output if args.output else in_dir
        if args.output and args.output.is_file():
            print("[ERROR] Output must be a directory when input is a directory.", file=sys.stderr)
            sys.exit(1)

        ogg_files = [p for p in in_dir.rglob("*") if p.is_file() and is_ogg(p)]
        if not ogg_files:
            print("No OGG files found.")
            return

        for src in ogg_files:
            rel = src.relative_to(in_dir)
            dst = (out_dir / rel).with_suffix(".mp3")
            convert_file(src, dst, args.bitrate, args.vbr, args.overwrite)

if __name__ == "__main__":
    main()
Back to top arrow

评论

发表回复