Giter VIP home page Giter VIP logo

Comments (10)

marcwebbie avatar marcwebbie commented on August 25, 2024

What was the bitrate of the original file?

from pydub.

jiaaro avatar jiaaro commented on August 25, 2024

He didn't say but since the resulting file was only a couple hundred bytes different in size (< 1% change), I assume it was also 128k

from pydub.

jiaaro avatar jiaaro commented on August 25, 2024

Perhaps we should explicitly pass the duration meta data to ffmpeg when it's an mp3 file? It feels kludgy to me especially since we'll probably have to end up adding special cases like this for lots of formats if we go this route.

Maybe this is an ffmpeg bug that we should just pass upstream?

from pydub.

marcwebbie avatar marcwebbie commented on August 25, 2024

I think that we should try reproducing this bug before doing anything.
Yes, it may be a ffmpeg issue. It may also be a matter of args passed to
ffmpeg by pydub. I will try reproducing with some mp3 and using ffprobe to
check.

Le 29 oct. 2013 12:09, "James Robert" [email protected] a Γ©crit :

Perhaps we should explicitly pass the duration meta data to ffmpeg when
it's an mp3 file? It feels kludgy to me especially since we'll probably
have to end up adding special cases like this for lots of formats if we go
this route.

Maybe this is an ffmpeg bug that we should just pass upstream?

β€”
Reply to this email directly or view it on GitHub.

from pydub.

marcwebbie avatar marcwebbie commented on August 25, 2024

Debugging turned out into some funny bitrate converting. See ffprobe output, the bitrate in the "format" dict.
it shows "bit_rate": "128009" for song.mp3 and "bit_rate": "128019" for song_with_bitrate.mp3.

I agree with you, it looks like a ffmpeg issue.

Code to test de issue:

# issue28.py

import shlex
import subprocess
import os

from pydub import AudioSegment


def test_pydub():
    print("original_song: godfather.mp3")
    original_song = 'godfather.mp3'

    print("Building 'song' AudioSegment with from_mp3(original_song)...")
    song = AudioSegment.from_mp3(original_song)

    print("Building 'song2' AudioSegment with from_file(original_song)...")
    song2 = AudioSegment.from_file(original_song)

    print("Exporting 'song' to mp3 as 'song.mp3'...")
    song.export("song.mp3", format="mp3")
    print("Exporting 'song' to mp3 with arg bitrate=128 as 'song_with_bitrate.mp3'...")
    song.export("song_with_bitrate.mp3", format="mp3", bitrate="128k")

    print("Exporting 'song2' to mp3 as 'song2.mp3'...")
    song2.export("song2.mp3", format="mp3")
    print("Exporting 'song2' to mp3 with arg bitrate=128 as 'song2_with_bitrate.mp3'...")
    song2.export("song2_with_bitrate.mp3", format="mp3", bitrate="128k")

    print("Getting exported files size...")
    original_song_size = os.path.getsize(original_song)

    song_size = os.path.getsize("song.mp3")
    song_with_bitrate_size = os.path.getsize("song_with_bitrate.mp3")

    song2_size = os.path.getsize("song2.mp3")
    song2_with_bitrate_size = os.path.getsize("song2_with_bitrate.mp3")

    print("Size of original_song: {}".format(original_song_size))
    print("Size of 'song.mp3': {}".format(song_size))
    print("size of 'song_with_bitrate.mp3': {}".format(song_with_bitrate_size))
    print("size of 'song2.mp3': {}".format(song2_size))
    print("size of 'song2_with_bitrate.mp3': {}".format(song2_with_bitrate_size))


def test_with_ffprobe():
    print("")
    print("ffprobe song.mp3")
    print("==========================================================")
    subprocess.call(
        shlex.split("ffprobe -v quiet -print_format json -show_format -show_streams song.mp3"))

    print("")
    print("ffprobe song_with_bitrate.mp3")
    print("==========================================================")
    subprocess.call(
        shlex.split("ffprobe -v quiet -print_format json -show_format -show_streams song_with_bitrate.mp3"))


if __name__ == "__main__":
    test_pydub()
    test_with_ffprobe()

The output confirms the issue:

[marc@arch pydub]$ python issue28.py 
original_song: godfather.mp3
Building 'song' AudioSegment with from_mp3(original_song)...
Building 'song2' AudioSegment with from_file(original_song)...
Exporting 'song' to mp3 as 'song.mp3'...
ffmpeg call:  ['ffmpeg', '-y', '-f', 'wav', '-i', '/tmp/tmp3egck9', '-f', 'mp3', '/tmp/tmp1f647m']
Exporting 'song' to mp3 with arg bitrate=128 as 'song_with_bitrate.mp3'...
ffmpeg call:  ['ffmpeg', '-y', '-f', 'wav', '-i', '/tmp/tmp7f51ep', '-b:a', '128k', '-f', 'mp3', '/tmp/tmpt56ya2']
Exporting 'song2' to mp3 as 'song2.mp3'...
ffmpeg call:  ['ffmpeg', '-y', '-f', 'wav', '-i', '/tmp/tmpecx3iy', '-f', 'mp3', '/tmp/tmpcgar9y']
Exporting 'song2' to mp3 with arg bitrate=128 as 'song2_with_bitrate.mp3'...
ffmpeg call:  ['ffmpeg', '-y', '-f', 'wav', '-i', '/tmp/tmp0pa7bt', '-b:a', '128k', '-f', 'mp3', '/tmp/tmp8rrgnc']
Getting exported files size...
Size of original_song: 2988022
Size of 'song.mp3': 2988635
size of 'song_with_bitrate.mp3': 2988870
size of 'song2.mp3': 2988635
size of 'song2_with_bitrate.mp3': 2988870

ffprobe song.mp3
==========================================================
{
    "streams": [
        {
            "index": 0,
            "codec_name": "mp3",
            "codec_long_name": "MP3 (MPEG audio layer 3)",
            "codec_type": "audio",
            "codec_time_base": "1/44100",
            "codec_tag_string": "[0][0][0][0]",
            "codec_tag": "0x0000",
            "sample_fmt": "s16p",
            "sample_rate": "44100",
            "channels": 2,
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/14112000",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 2635776000,
            "duration": "186.775510",
            "bit_rate": "128000",
            "disposition": {
                "default": 0,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0
            }
        }
    ],
    "format": {
        "filename": "song.mp3",
        "nb_streams": 1,
        "format_name": "mp3",
        "format_long_name": "MP2/3 (MPEG audio layer 2/3)",
        "start_time": "0.000000",
        "duration": "186.775510",
        "size": "2988635",
        "bit_rate": "128009",
        "tags": {
            "encoder": "Lavf55.12.100"
        }
    }
}

ffprobe song_with_bitrate.mp3
==========================================================
{
    "streams": [
        {
            "index": 0,
            "codec_name": "mp3",
            "codec_long_name": "MP3 (MPEG audio layer 3)",
            "codec_type": "audio",
            "codec_time_base": "1/44100",
            "codec_tag_string": "[0][0][0][0]",
            "codec_tag": "0x0000",
            "sample_fmt": "s16p",
            "sample_rate": "44100",
            "channels": 2,
            "bits_per_sample": 0,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/14112000",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 2635776000,
            "duration": "186.775510",
            "bit_rate": "128000",
            "disposition": {
                "default": 0,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0
            }
        }
    ],
    "format": {
        "filename": "song_with_bitrate.mp3",
        "nb_streams": 1,
        "format_name": "mp3",
        "format_long_name": "MP2/3 (MPEG audio layer 2/3)",
        "start_time": "0.000000",
        "duration": "186.775510",
        "size": "2988870",
        "bit_rate": "128019",
        "tags": {
            "encoder": "Lavf55.12.100"
        }
    }
}

from pydub.

jiaaro avatar jiaaro commented on August 25, 2024

Nice detective work! I have mixed feelings about doing nothing though.

What do you think?

from pydub.

marcwebbie avatar marcwebbie commented on August 25, 2024

I've found some flaws on pydub due to that issue, it's more complicated than we've thought, keep the issue open. I'm working on something to lessen this issue.

from pydub.

lepinsk avatar lepinsk commented on August 25, 2024

Yikes; sorry, didn't mean for my issue to show up here. Sorry about that...

from pydub.

jpasden avatar jpasden commented on August 25, 2024

I'm running into this same issue, and the discrepancies are larger. Like 12s VS 14s.

It's bad enough that I have to output to WAV (no problems there) and use other software to convert to MP3.

(@jiaaro I'm the guy that posted to StackOverflow the other day about adding silence. Love pyDub so much! If I can find a workaround for this, it will be just perfect...)

from pydub.

jiaaro avatar jiaaro commented on August 25, 2024

@jpasden So far this appears to be an issue with ffmpeg - you can try upgrading ffmpeg, or using the libav fork instead, which has a better reputation for fixing bugs.

edit: Other people around the internet seems to be seeing this issue as well. Some people seem to be having success with MP3Diags and mp3val, but the first thing I'd try is using the latest libav instead of ffmpeg.

from pydub.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.