gpac / gpac

GPAC Ultramedia OSS for Video Streaming & Next-Gen Multimedia Transcoding, Packaging & Delivery
https://gpac.io
GNU Lesser General Public License v2.1
2.8k stars 532 forks source link

Demuxing ALAC audio tracks from .mp4 using mp4box #358

Closed Foaly closed 5 years ago

Foaly commented 8 years ago

Hello! I encountered a problem, when extracting audio tracks from a .mp4 container, that looks like a bug. I have an .mp4 file that contains multiple audio tracks. The audio tracks are encoded using the ALAC codec. I want to extract those into seperate audio files using mp4box.

What I've tryed so far for extracting a track is this:

mp4box -single 1 "inputfile.mp4" -out "outputfile.m4a"

What happens is, it works as that a outputfile.m4a is created, but something with the header/codec/file info seems to be malformated. I can open and play the file in VLC, but it fails to open with Windows Media Player/Windows Media Foundation (which I need). So either I am doing something wrong during the extraction or mp4box puts the file in a weird format.

The output of mp4box -info -v "outputfile.mp4" looks like this:

[iso file] Current top box start before parsing 0
[iso file] Read Box type ftyp size 20 start 0
[iso file] Current top box start before parsing 20
[iso file] Read Box type mdat size 8555577 start 20
[iso file] Current top box start before parsing 8555597
[iso file] Read Box type free size 75 start 8555597
[iso file] Current top box start before parsing 8555672
[iso file] Read Box type moov size 4895 start 8555672
[iso file] Read Box type mvhd size 108 start 8555680
[iso file] Read Box type trak size 4779 start 8555788
[iso file] Read Box type tkhd size 92 start 8555796
[iso file] Read Box type mdia size 4679 start 8555888
[iso file] Read Box type mdhd size 32 start 8555896
[iso file] Read Box type hdlr size 55 start 8555928
[iso file] Read Box type minf size 4584 start 8555983
[iso file] Read Box type smhd size 16 start 8555991
[iso file] Read Box type dinf size 36 start 8556007
[iso file] Read Box type dref size 28 start 8556015
[iso file] Read Box type url  size 12 start 8556031
[iso file] Read Box type stbl size 4524 start 8556043
[iso file] Read Box type stsd size 108 start 8556051
[iso file] Read Box type alac size 92 start 8556067
[iso file] Read Box type stts size 24 start 8556159
[iso file] Read Box type stsc size 40 start 8556183
[iso file] Read Box type stsz size 3936 start 8556223
[iso file] Read Box type stco size 408 start 8560159
[iso file] Read Box type alac size 36 start 28
[iso file] Read Box type btrt size 20 start 64
* Movie Info *
        Timescale 600 - 1 track
        Computed Duration 00:01:30.928 - Indicated Duration 00:01:30.928
        Fragmented File: no
        File Brand isom - version 1
        Created: GMT Thu Dec 17 14:35:48 2015
        Modified: GMT Thu Dec 17 14:35:48 2015

File has no MPEG4 IOD/OD

Track # 1 Info - TrackID 1 - TimeScale 44100
Media Duration 00:01:30.929 - Indicated Duration 00:01:30.929
Media Info: Language "und (und)" - Type "soun:alac" - 979 samples
Audio Track - Sample Rate 44100 - 2 channel(s)
[ISOM Tools] codec parameters not known - setting codecs string to default value "alac"
        RFC6381 Codec Parameters: alac
        All samples are sync

I also tryed extracting the audio tracks using the -raw flag like this:

mp4box -raw 1 "inputfile.mp4"

It creates a inputfile.mp4_track1.alac file, which I can't open in any player (not even VLC). Looking at it in a HEX editor it looks like the raw data segment (which makes sense I guess), but I can't get mp4box to put it back into a .m4a which I can play.

Here is a small python script to reproduce the above error:

import os
import subprocess

def combineIntoOneMP4():
    executionDir = os.path.dirname(os.path.realpath(__file__))
    inputFile = os.path.join(executionDir, "TechTalk_CC_music.m4a")
    outputFile = os.path.join(executionDir, "testout.mp4")

    # main track not disabled
    callArgs = ["mp4box", "-add", inputFile + "#ID=Z", outputFile]

    for i in range(0, 4):
        # other tracks disabled
        callArgs.extend(["-add", inputFile + "#ID=Z:disable"])

    #print(callArgs)
    subprocess.check_call(callArgs)
    print("Combined 5 tracks into one MP4 file: " + os.path.basename(outputFile))

def extractAudioTracks():
    executionDir = os.path.dirname(os.path.realpath(__file__))
    inputFile = os.path.join(executionDir, "testout.mp4")

    for i in range(0, 5):
        outputFile = os.path.join(executionDir, "extractedTrack_" + str(i + 1) + ".m4a")
        callArgs = ["mp4box", "-single", str(i + 1), inputFile, "-out", outputFile]
        #print(callArgs)
        subprocess.check_call(callArgs)

    print("Extracted tracks into seperate files.")

# call functions
combineIntoOneMP4()
extractAudioTracks()

Here is a zip file containing the TechTalk_CC_music.m4a track that I used for testing and in the example: Mp4Box Test.zip

So I guess the question is am I doing anything wrong? Am I maybe missing some flag while extracting? Or is mp4box simply producing wrong results? I hope somebody can point me in the right direction. Thanks in advance!

combucha commented 8 years ago

I was curious where you get this album in lossless format. After checking spectrals can only say that it's transcoded from mp3. The same quality has 192kpbs pack available for free2dl.

This mp4 looks like created with ffmpeg, you can't just throw raw alac and import it back with mp4box afaik. What happen if you try to extract for example 1st track this way: mp4box -add [yourmultitracksfile].mp4#1 track1.mp4, is it playable?

Foaly commented 8 years ago

Hi. First of all thanks for looking into it!

Yes the testfile is indeed a transcoded mp3 file. I realize now that it's not an ideal testfile, but I wanted to upload something that is under CC license so that everybody else can test it. Sorry about that! The problem persists though when using ALAC files from this site: http://www.linnrecords.com/linn-downloads-testfiles.aspx

This mp4 looks like created with ffmpeg, you can't just throw raw alac and import it back with mp4box afaik.

What mp4 file do you mean? The testout.mp4 is created by mp4box using the above script. If you mean the TechTalk_CC_music.m4a file, forget about it, like I said it was a bad example and the problem persits with "real" ALAC files (like this one).

I tryed using mp4box -add [yourmultitracksfile].mp4#1 track1.mp4 and the results are the same. I can't open them with Windows Media Foundation / Windows Media Player. Also another problem arises when I try to extract a track other then the first one using the add method. The track is at position 1, but the track ID and the enabled/disabled state from the multitrack file is kept. Here is a example info from a track created like this mp4box -add testout.mp4#2 track2.m4a:

>mp4box -info track2.m4a
* Movie Info *
        Timescale 44100 - 1 track
        Computed Duration 00:00:09.008 - Indicated Duration 00:00:09.008
        Fragmented File: no
        File suitable for progressive download (moov before mdat)
        File Brand M4A  - version 1
        Created: GMT Mon Dec 21 16:10:32 2015
        Modified: GMT Mon Dec 21 16:10:32 2015

File has root IOD (9 bytes)
Scene PL 0xff - Graphics PL 0xff - OD PL 0xff
Visual PL: No visual capability required (0xff)
Audio PL: No audio capability required (0xff)
No streams included in root OD

Track # 1 Info - TrackID 2 - TimeScale 44100                         <--- here
Media Duration 00:00:09.008 - Indicated Duration 00:00:09.008
Track is disabled                                                    <--- and here
Media Info: Language "und (und)" - Type "soun:alac" - 97 samples
Audio Track - Sample Rate 44100 - 2 channel(s)
        RFC6381 Codec Parameters: alac
        All samples are sync
combucha commented 8 years ago

Yep, I was talking about file you zipped (that one to forget). From your first post, unplayable file created using -single method will play in WMP after remux outputfile.m4a (mp4box -add). How does look -info of your multitrack mp4 file?

Foaly commented 8 years ago

That sounds awesome! Sadly I can't reproduce it. If I use the my above script to create a multitrack file (called testout.mp4), then extract it using mp4box -single 1 testout.mp4 -out extrackedTrack_1.m4a and then remux it using mp4box -add extrackedTrack_1.m4a outputfile.m4a it still won't open in WMP... Is that the right command or did you use something different for remuxing?

The -info of my multitrack mp4 looks like this:

>mp4box -info -v testout.mp4
[iso file] Current top box start before parsing 0
[iso file] Read Box type ftyp size 20 start 0
[iso file] Current top box start before parsing 20
[iso file] Read Box type moov size 4822 start 20
[iso file] Read Box type mvhd size 108 start 28
[iso file] Read Box type iods size 21 start 136
[iso file] Read Box type trak size 937 start 157
[iso file] Read Box type tkhd size 92 start 165
[iso file] Read Box type mdia size 837 start 257
[iso file] Read Box type mdhd size 32 start 265
[iso file] Read Box type hdlr size 33 start 297
[iso file] Read Box type minf size 764 start 330
[iso file] Read Box type smhd size 16 start 338
[iso file] Read Box type dinf size 36 start 354
[iso file] Read Box type dref size 28 start 362
[iso file] Read Box type url  size 12 start 378
[iso file] Read Box type stbl size 704 start 390
[iso file] Read Box type stsd size 108 start 398
[iso file] Read Box type alac size 92 start 414
[iso file] Read Box type stts size 32 start 506
[iso file] Read Box type stsc size 52 start 538
[iso file] Read Box type stsz size 408 start 590
[iso file] Read Box type stco size 96 start 998
[iso file] Read Box type alac size 36 start 28
[iso file] Read Box type btrt size 20 start 64
[iso file] Read Box type trak size 937 start 1094
[iso file] Read Box type tkhd size 92 start 1102
[iso file] Read Box type mdia size 837 start 1194
[iso file] Read Box type mdhd size 32 start 1202
[iso file] Read Box type hdlr size 33 start 1234
[iso file] Read Box type minf size 764 start 1267
[iso file] Read Box type smhd size 16 start 1275
[iso file] Read Box type dinf size 36 start 1291
[iso file] Read Box type dref size 28 start 1299
[iso file] Read Box type url  size 12 start 1315
[iso file] Read Box type stbl size 704 start 1327
[iso file] Read Box type stsd size 108 start 1335
[iso file] Read Box type alac size 92 start 1351
[iso file] Read Box type stts size 32 start 1443
[iso file] Read Box type stsc size 52 start 1475
[iso file] Read Box type stsz size 408 start 1527
[iso file] Read Box type stco size 96 start 1935
[iso file] Read Box type alac size 36 start 28
[iso file] Read Box type btrt size 20 start 64
[iso file] Read Box type trak size 937 start 2031
[iso file] Read Box type tkhd size 92 start 2039
[iso file] Read Box type mdia size 837 start 2131
[iso file] Read Box type mdhd size 32 start 2139
[iso file] Read Box type hdlr size 33 start 2171
[iso file] Read Box type minf size 764 start 2204
[iso file] Read Box type smhd size 16 start 2212
[iso file] Read Box type dinf size 36 start 2228
[iso file] Read Box type dref size 28 start 2236
[iso file] Read Box type url  size 12 start 2252
[iso file] Read Box type stbl size 704 start 2264
[iso file] Read Box type stsd size 108 start 2272
[iso file] Read Box type alac size 92 start 2288
[iso file] Read Box type stts size 32 start 2380
[iso file] Read Box type stsc size 52 start 2412
[iso file] Read Box type stsz size 408 start 2464
[iso file] Read Box type stco size 96 start 2872
[iso file] Read Box type alac size 36 start 28
[iso file] Read Box type btrt size 20 start 64
[iso file] Read Box type trak size 937 start 2968
[iso file] Read Box type tkhd size 92 start 2976
[iso file] Read Box type mdia size 837 start 3068
[iso file] Read Box type mdhd size 32 start 3076
[iso file] Read Box type hdlr size 33 start 3108
[iso file] Read Box type minf size 764 start 3141
[iso file] Read Box type smhd size 16 start 3149
[iso file] Read Box type dinf size 36 start 3165
[iso file] Read Box type dref size 28 start 3173
[iso file] Read Box type url  size 12 start 3189
[iso file] Read Box type stbl size 704 start 3201
[iso file] Read Box type stsd size 108 start 3209
[iso file] Read Box type alac size 92 start 3225
[iso file] Read Box type stts size 32 start 3317
[iso file] Read Box type stsc size 52 start 3349
[iso file] Read Box type stsz size 408 start 3401
[iso file] Read Box type stco size 96 start 3809
[iso file] Read Box type alac size 36 start 28
[iso file] Read Box type btrt size 20 start 64
[iso file] Read Box type trak size 937 start 3905
[iso file] Read Box type tkhd size 92 start 3913
[iso file] Read Box type mdia size 837 start 4005
[iso file] Read Box type mdhd size 32 start 4013
[iso file] Read Box type hdlr size 33 start 4045
[iso file] Read Box type minf size 764 start 4078
[iso file] Read Box type smhd size 16 start 4086
[iso file] Read Box type dinf size 36 start 4102
[iso file] Read Box type dref size 28 start 4110
[iso file] Read Box type url  size 12 start 4126
[iso file] Read Box type stbl size 704 start 4138
[iso file] Read Box type stsd size 108 start 4146
[iso file] Read Box type alac size 92 start 4162
[iso file] Read Box type stts size 32 start 4254
[iso file] Read Box type stsc size 52 start 4286
[iso file] Read Box type stsz size 408 start 4338
[iso file] Read Box type stco size 96 start 4746
[iso file] Read Box type alac size 36 start 28
[iso file] Read Box type btrt size 20 start 64
[iso file] Current top box start before parsing 4842
[iso file] Read Box type mdat size 3953388 start 4842
[iso file] Current top box start before parsing 3958230
[iso file] Read Box type free size 75 start 3958230
* Movie Info *
        Timescale 44100 - 5 tracks
        Computed Duration 00:00:09.008 - Indicated Duration 00:00:09.008
        Fragmented File: no
        File suitable for progressive download (moov before mdat)
        File Brand isom - version 1
        Created: GMT Tue Dec 22 10:46:46 2015
        Modified: GMT Tue Dec 22 10:46:46 2015

File has root IOD (9 bytes)
Scene PL 0xff - Graphics PL 0xff - OD PL 0xff
Visual PL: No visual capability required (0xff)
Audio PL: No audio capability required (0xff)
No streams included in root OD

Track # 1 Info - TrackID 1 - TimeScale 44100
Media Duration 00:00:09.008 - Indicated Duration 00:00:09.008
Media Info: Language "und (und)" - Type "soun:alac" - 97 samples
Audio Track - Sample Rate 44100 - 2 channel(s)
[ISOM Tools] codec parameters not known - setting codecs string to default value "alac"
        RFC6381 Codec Parameters: alac
        All samples are sync

Track # 2 Info - TrackID 2 - TimeScale 44100
Media Duration 00:00:09.008 - Indicated Duration 00:00:09.008
Track is disabled
Media Info: Language "und (und)" - Type "soun:alac" - 97 samples
Audio Track - Sample Rate 44100 - 2 channel(s)
[ISOM Tools] codec parameters not known - setting codecs string to default value "alac"
        RFC6381 Codec Parameters: alac
        All samples are sync

Track # 3 Info - TrackID 3 - TimeScale 44100
Media Duration 00:00:09.008 - Indicated Duration 00:00:09.008
Track is disabled
Media Info: Language "und (und)" - Type "soun:alac" - 97 samples
Audio Track - Sample Rate 44100 - 2 channel(s)
[ISOM Tools] codec parameters not known - setting codecs string to default value "alac"
        RFC6381 Codec Parameters: alac
        All samples are sync

Track # 4 Info - TrackID 4 - TimeScale 44100
Media Duration 00:00:09.008 - Indicated Duration 00:00:09.008
Track is disabled
Media Info: Language "und (und)" - Type "soun:alac" - 97 samples
Audio Track - Sample Rate 44100 - 2 channel(s)
[ISOM Tools] codec parameters not known - setting codecs string to default value "alac"
        RFC6381 Codec Parameters: alac
        All samples are sync

Track # 5 Info - TrackID 5 - TimeScale 44100
Media Duration 00:00:09.008 - Indicated Duration 00:00:09.008
Track is disabled
Media Info: Language "und (und)" - Type "soun:alac" - 97 samples
Audio Track - Sample Rate 44100 - 2 channel(s)
[ISOM Tools] codec parameters not known - setting codecs string to default value "alac"
        RFC6381 Codec Parameters: alac
        All samples are sync
combucha commented 8 years ago

Ye, looks like you wrapped 5 x recit16bit.m4a into 1 file, will be hard to say if extracted track no#3 is not actually no#1 ;)

Step by step what I've done: mp4box -add recit16bit.m4a -add TechTalk_CC_music.m4a testout.m4a (don't try to play combined testout.m4a, it hang my WMP) mp4box -add testout.m4a#1 extracted_track_1.m4a mp4box -add testout.m4a#2 extracted_track_2.m4a

Both extracted tracks playing fine in my WMP11 with alac decoder (DC-Bass Source v1.3.0) MP4Box from GPAC version 0.5.2-DEV-rev1110-g9f2bf6e-master

Almost forgot, don't create .mp4 as output for WMP, decoder won't handle it, stick to .m4a -single method probably creates proper file (as VLC play it without errors), but wmp decoder can't play it probably of moov after mdat container structure -single method used on my testout.m4a throws mp4box into infinite loop causing 100%CPU For above reasons try to modify your script to extracting tracks with -add inputFile#ID method.

Foaly commented 8 years ago

From my experience the tracks stay in the same order when inserting/extracting.

I followed your exact steps and I could not reproduce the behaviour.

I'm on a windows 10 machine and I am using windows media player version 12.0. (I don't know the version of the ALAC decoder used) Mp4box is also from gpac-0.5.2-DEV-rev1110-g9f2bf6e-master-win32

edit: could you maybe upload one of the extracted_track files so I could test if it's a playback problem or something with mp4box?

combucha commented 8 years ago

Does your WMP12 is able to play single original recit16bit.m4a ?

Foaly commented 8 years ago

yep that one is playing without problems. (both WMP12 and windows media foundation, the underlying framework)

combucha commented 8 years ago

Does this extracted track from my step-by-step example play in your WMP? http://www54.zippyshare.com/v/u5ljgD8c/file.html

Foaly commented 8 years ago

Nope that file won't open in my WMP.

combucha commented 8 years ago

Ok, support from my side ends here. From my p.o.v. it's your WMP alac decoder issue. Can't help you with fixing it (other system & WMP). I've checked also my mp4box extracted_track_1.m4a in iTunes, can play it without problem.

Foaly commented 8 years ago

Why was this being closed? The issue still persists. I could work around it by using avconv, but for mp4box its still broken. The header is changed when the file is extracted.

jeanlf commented 8 years ago

closed since it appears to be an issue with the decoder, not with mp4box (based on the above discussion). If not please reopen and post mp4 file and working extracted track

Foaly commented 8 years ago

OK I prepeared some sample files:

  1. Original ALAC file (recit16bit.m4a)
  2. Mp4 file containing the original file twice (2trackfile.mp4)
  3. File extracted with MP4Box (mp4boxExtracted.m4a)
  4. File extracted with avconv (avconcExtracted.m4a)

Unfortunatelly I had to zip it, but here it is: Gpac Error.zip

I created the file with the two tracks (number 2) like this: mp4box 2trackfile.mp4 -add recit16bit.m4a#ID=Z -add recit16bit.m4a#ID=Z:disable

Then I extracted it like this (file number 3): mp4box -single 2 2trackfile.mp4 -out mp4boxExtracted.m4a

The last file is created like this: avconv.exe -i 2trackfile.mp4 -map 0:1 -acodec copy avconvExtracted.m4a

Like explained above the file extracted with mp4box won't open with Windows Media Foundation or with Core Audio. Extracting with avconv results in a working file. If you run a diff on the file 1, 3 and 4 you can see that pretty much the only difference between number 3 and 1 & 4 is right at the beginning (the rest are just rearranged chuncks). The 4 bytes after ftyp (offset 0x8 to 0xb) are changed from M4A to isom, which changes the file type. To me this makes no sense. Putting a file in a container and getting in it out again should not change the header of the file. Maybe you have some more insight on that. But to me this definitly seems like a bug.

jeanlf commented 8 years ago

extracted files play fine in VLC

If you change the brand of the mp4box extracted file using -brand, does it play with WMF ?

Foaly commented 8 years ago

If I remember correctly I tryed differend -brand settings, when I first encountered this bug and it didn't work, but it wasn't very systematically. What setting should I use?

jeanlf commented 8 years ago

actually the brand is the same on the mp4box extracted and the source file so this is likely not the issue.

Could your try:

MP4Box -add mp4boxExtracted.m4a#2 -new test.mp4

and check if the resulting file plays ?

Foaly commented 8 years ago

I tested this and the resulting file does not open with Windows Media Foundation.

jeanlf commented 8 years ago

I just figured out that 2trackfile.mp4 has 4 tracks in what you attached, is this normal ?

could you try removing all the tracks except the target one from the main file ? eg

MP4Box -rem 1 -rem 3 -rem 4 2trackfile.mp4 -out test.mp4

and check the resulting test.mp4 ?

Foaly commented 8 years ago

aaah damn it... That is an error on my side. I ran the "packing command" twice, because I forgot the :disable the first time. But the output file did not get overwritten. The two tracks were just appended. (as -add suggests...) 2trackfile.mp4 should only have two tracks. Sorry about the confusion. I attached a new zip with the correct files. Gpac Error.zip

But I also tried removing the extra 3 tracks (and 1 extra track with the correct file) with your above code and the file won't open.

Foaly commented 8 years ago

So I guess the issue should at least be reopened, since it still exists.

rbouqueau commented 8 years ago

I reopened although I don't follow this issue.

jeanlf commented 8 years ago

Have you tried changing the brand ? avconv seems to force 'M4A ' in 512:

MP4Box -brand "M4A :512" -ab iso2 mp4boxExtracted.m4a

or rebuilding a new file, with brand adding:

MP4Box -add mp4boxExtracted.m4a#2 -brand "M4A :512" -ab iso2 -new test.mp4

rbouqueau commented 8 years ago

Do we have news on this?

jeanlf commented 5 years ago

closing, no news