Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > General > Audio encoding

Reply
 
Thread Tools Search this Thread Display Modes
Old 20th May 2016, 03:52   #1  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Split ac3 in 5.1 and 2.0

Quote:
Originally Posted by tebasuna51 View Post
Maybe you have an AC3 with 2 kind of frames (a TV capture?, movie and commercials).

Try run:

SplitAc3 audio.ac3

and put the log file created.
I am using this to fix an AC3 stream that switches between 2.0 and 5.1, and am following your directions from here to insert silences in place of the 2.0 frames that were extracted. At one point in my logfile though, I get this:

Code:
Time: 5981568 ms.	Skipped: 768 bytes	(Maybe: 13 ms.)
Time: 5981581 ms.	Written: 1 frames 2.0	( 32 ms.)
Time: 5981613 ms.	Skipped: 256 bytes	(Maybe: 10 ms.)
Should I simply do

Code:
eac3to file_n.ac3 file_n+1.ac3 -edit=1:39:41.568,55ms -silence
The 'Maybe' is giving me pause.

ED: using 55ms there appears to have been fine, but I have another question. The original track has a delay of 10ms which eac3to says it could not fix:

Code:
[a02] A remaining delay of +10ms could not be fixed.
Is this then fixed by SplitAc3? There is nothing in the log about it:

Code:
FileSize : 390893984 bytes
---------- First valid Header
Time eq. : 6980249 ms.
SamplCod : 0 (0:48, 1:44.1, 2:32 KHz.)
BitRate  : 448 Kb/s
ChanMode : 7 (1:1/0, 2:2/0, 3:3/0, 4:2/1, 5:3/1, 6:2/2, 7:3/2)
FrameSize: 1792 bytes
---------- Process ( 25.000000 fps is used for Trim)
Time: 0 ms.	Written: 10993 frames 5.1	( 351776 ms.)	Trim(0, 8793)
...
10ms is such a minute difference that it's very difficult for me to judge. I'm tempted to just leave it alone but figured I would ask here all the same.

Last edited by bilditup1; 20th May 2016 at 04:42.
bilditup1 is offline   Reply With Quote
Old 20th May 2016, 07:06   #2  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Running into some unexplained weirdness with eac3to and/or splitac3 on a different file. Not sure why but when I try to insert silences in this file, they are inserted one minute too early (in comparison with the timestamp given by the splitac3 log, which is in fact accurate). I have double-checked my math (ms --> hhmmss.ms) a dozen times on this, and it's not wrong either. The silences I'm attempting to insert are quite large, per the log:

Code:
FileSize : 289742432 bytes
---------- First valid Header
Time eq. : 5173972 ms.
SamplCod : 0 (0:48, 1:44.1, 2:32 KHz.)
BitRate  : 448 Kb/s
ChanMode : 7 (1:1/0, 2:2/0, 3:3/0, 4:2/1, 5:3/1, 6:2/2, 7:3/2)
FrameSize: 1792 bytes
---------- Process ( 29.970000 fps is used for Trim)
Time: 0 ms.	Written: 50980 frames 5.1	( 1631360 ms.)	Trim(0, 48891)
Time: 1631360 ms.	Written: 1873 frames 2.0	( 59936 ms.)
Time: 1691296 ms.	Written: 40166 frames 5.1	( 1285312 ms.)	Trim(50688, 89208)
Time: 2976608 ms.	Written: 1870 frames 2.0	( 59840 ms.)
Time: 3036448 ms.	Written: 11080 frames 5.1	( 354560 ms.)	Trim(91002, 101627)
Time: 3391008 ms.	Written: 942 frames 2.0	( 30144 ms.)
Time: 3421152 ms.	Skipped: 768 bytes	(Maybe: 109 ms.)
Time: 3421261 ms.	Written: 938 frames 2.0	( 30016 ms.)
Time: 3451277 ms.	Written: 42827 frames 5.1	( 1370464 ms.)	Trim(103435, 144507)
Time: 4821741 ms.	Written: 1871 frames 2.0	( 59872 ms.)
Time: 4881613 ms.	Written: 13423 frames 5.1	( 429536 ms.)	Trim(146302, 159174)
---------- End of File
Total time: 5311149 ms. at EOF
T. written: 158476 frames 5.1.
T. written: 7494 frames 2.0.
And I didn't have any sort of problem like this when I was just putting in small silences of 32-224ms in the file I was working with in my last post. Adding one minute to the -edit parameter for each deleted 2.0 section fixed this and sync is perfect. Anyone?
I can upload the file somewhere temporarily if anybody is interested enough to look at this.

ED: The same thing just happened with another recording. Weirdness all around...

Last edited by bilditup1; 20th May 2016 at 07:50. Reason: added file offer
bilditup1 is offline   Reply With Quote
Old 20th May 2016, 10:26   #3  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,890
Quote:
Originally Posted by bilditup1 View Post
Code:
...
Time: 3391008 ms.	Written: 942 frames 2.0	( 30144 ms.)
Time: 3421152 ms.	Skipped: 768 bytes	(Maybe: 109 ms.)
Time: 3421261 ms.	Written: 938 frames 2.0	( 30016 ms.)
...
The Skipped fragments are bytes without valid AC3 headers, then I try to suposse the duration equivalence bassed in previous framelength, for that the "Maybe..."

But we never can be sure if that is correct, here show a strange equivalence: 768 bytes is the length of a typical 2.0 192 Kb/s 48 KHz frame (32 ms), here show 109 ms.

I don't know if is a problem of my soft or a corrupt AC3 file.

Quote:
I can upload the file somewhere temporarily if anybody is interested enough to look at this.
Yes, please.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Old 20th May 2016, 21:02   #4  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Quote:
Originally Posted by tebasuna51 View Post
Yes, please.
These are the problem files where I have to add a minute to the edit parameter in eac3to to have the silence put in the right place. Plus their logs.

File1_final_track2_51.ac3
File1_final_track2.log
File2_final_track2_51.ac3
File2_final_track2.log

I can also put the file I was working on that didn't have this issue up if you think it'll be useful.

Last edited by bilditup1; 22nd May 2016 at 23:23. Reason: Typo
bilditup1 is offline   Reply With Quote
Old 21st May 2016, 07:51   #5  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,890
I need the original files to analize the problem.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Old 22nd May 2016, 23:15   #6  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Quote:
Originally Posted by tebasuna51 View Post
I need the original files to analyze the problem.
Sorry, of course you do. Here they are.

File1_final_track2.ac3
File2_final_track2.ac3
bilditup1 is offline   Reply With Quote
Old 23rd May 2016, 11:10   #7  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,890
Quote:
Originally Posted by bilditup1 View Post
Sorry, of course you do. Here they are.
Thanks.

Well, your ac3's are a mix of this kinds:

5.1 448 Kb/s with 1792 bytes per frame
2.0 192 Kb/s with 768 bytes per frame
2.0 56 Kb/s with 224 bytes per frame

Even there are some buggy frames with headers showing a framelength but finising with another framelength.

Sorry, but my soft (SplitAc3) is not so smart to manage this situation.

The extraction of 5.1 stream works very well, but fails when try to calculate the duration of 2.0 frames because there are two kind of frames.

For this strange case (is the first time I see that) a manual resync is needed, like seems you already do.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Old 23rd May 2016, 12:08   #8  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,890
BTW if a have a TV capture with commercials, like seems you have, my way to recode the movie without commercials was this:

Using the log file, in your second post, with only the data of 5.1 streams:

Code:
---------- Process ( 29.970000 fps)     frames      Trim
                                        ------ --------------------
Written: 50980 frames 5.1 (1631360 ms.) 48892  Trim(0, 48891)
Written: 40166 frames 5.1 (1285312 ms.) 38521  Trim(x1, x1 + 38520)
Written: 11080 frames 5.1 ( 354560 ms.) 10626  Trim(x2, x2 + 10625)
Written: 42827 frames 5.1 (1370464 ms.) 41073  Trim(x3, x3 + 41072)
Written: 13423 frames 5.1 ( 429536 ms.) 12873  Trim(x4, x4 + 12872)
Seems there are 4 commercial cuts, I need locate the video frames when begin the next parts of the movie x1, x2, x3 and x4 and recode the video with these trims:

Trim(0, 48891) + Trim(x1, x1 + 38520) + Trim(x2, x2 + 10625) + Trim(x3, x3 + 41072) + Trim(x4, x4 + 12872)

After that you can add the ac3 5.1 to video and must be in sync.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Old 23rd May 2016, 23:46   #9  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Quote:
Originally Posted by tebasuna51 View Post
BTW if a have a TV capture with commercials, like seems you have, my way to recode the movie without commercials was this:

Using the log file, in your second post, with only the data of 5.1 streams:

Code:
---------- Process ( 29.970000 fps)     frames      Trim
                                        ------ --------------------
Written: 50980 frames 5.1 (1631360 ms.) 48892  Trim(0, 48891)
Written: 40166 frames 5.1 (1285312 ms.) 38521  Trim(x1, x1 + 38520)
Written: 11080 frames 5.1 ( 354560 ms.) 10626  Trim(x2, x2 + 10625)
Written: 42827 frames 5.1 (1370464 ms.) 41073  Trim(x3, x3 + 41072)
Written: 13423 frames 5.1 ( 429536 ms.) 12873  Trim(x4, x4 + 12872)
Seems there are 4 commercial cuts, I need locate the video frames when begin the next parts of the movie x1, x2, x3 and x4 and recode the video with these trims:

Trim(0, 48891) + Trim(x1, x1 + 38520) + Trim(x2, x2 + 10625) + Trim(x3, x3 + 41072) + Trim(x4, x4 + 12872)

After that you can add the ac3 5.1 to video and must be in sync.
Yes, that's what I ended up doing for the next x264 encodes, but I didn't want to redo the ones I had already done (AVS MT too crashy so had to move back to ST + avstp which isn't nearly as fast).
bilditup1 is offline   Reply With Quote
Old 23rd May 2016, 23:48   #10  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Quote:
Originally Posted by tebasuna51 View Post
Thanks.

Well, your ac3's are a mix of this kinds:

5.1 448 Kb/s with 1792 bytes per frame
2.0 192 Kb/s with 768 bytes per frame
2.0 56 Kb/s with 224 bytes per frame

Even there are some buggy frames with headers showing a framelength but finising with another framelength.

Sorry, but my soft (SplitAc3) is not so smart to manage this situation.

The extraction of 5.1 stream works very well, but fails when try to calculate the duration of 2.0 frames because there are two kind of frames.

For this strange case (is the first time I see that) a manual resync is needed, like seems you already do.
Does this explain why I had to add a minute to the timestamp I specified in the edit parameter for eac3to in order to add silence in the right place?
bilditup1 is offline   Reply With Quote
Old 23rd May 2016, 23:51   #11  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Also, I'm curious - is there a way to add dummy SL/SR/C/LFE channels to a section of 2.0 AC3 and then cut it back into a 5.1 AC3 without doing any reencoding?
In any case. This software basically saved me these past few days. So thanks!

Last edited by bilditup1; 24th May 2016 at 10:26. Reason: typo
bilditup1 is offline   Reply With Quote
Old 24th May 2016, 07:45   #12  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,890
Quote:
Originally Posted by bilditup1 View Post
Does this explain why I had to add a minute to the timestamp I specified in the edit parameter for eac3to in order to add silence in the right place?
The durations of 2.0 parts are wrong because there are two kinds of AC3 frames, but I can't easily know the amount of errors.

Quote:
Originally Posted by bilditup1 View Post
Also, I'm curious - is there a way to add dummy SR/SR/C/LFE channels to a section of 2.0 AC3 and then cut it back into a 5.1 AC3 without doing any reencoding?
Nope, to convert a 2.0 to 5.1 you need recode the stream, at least all the 2.0 parts.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Old 24th May 2016, 10:25   #13  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Quote:
Originally Posted by tebasuna51 View Post
The durations of 2.0 parts are wrong because there are two kinds of AC3 frames, but I can't easily know the amount of errors.
Aha, I see. Thanks for clarifying.

Quote:
Originally Posted by tebasuna51 View Post
Nope, to convert a 2.0 to 5.1 you need recode the stream, at least all the 2.0 parts.
Rats. Ah well, thanks again for explaining.

Wait, since my goal is to encode to AAC - is there a program for stitching m4a accurate enough that I could just downmix the 5.1 part to 2.0 and encode in AAC, then encode the 2.0 parts of the file separately, and then paste those in at the points indicated by the splitac3 log?
bilditup1 is offline   Reply With Quote
Old 24th May 2016, 13:16   #14  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,890
The 2.0 parts are corrupt (because 2 kind of frames) and can't be used to recode.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Old 25th May 2016, 01:56   #15  |  Link
bilditup1
Registered User
 
bilditup1's Avatar
 
Join Date: Feb 2004
Location: NYC
Posts: 124
Quote:
Originally Posted by tebasuna51 View Post
The 2.0 parts are corrupt (because 2 kind of frames) and can't be used to recode.
Right...oh well. Thanks again for taking the time.
bilditup1 is offline   Reply With Quote
Old 2nd October 2018, 10:05   #16  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,890
Answer to Qarmaa pm:
Quote:
Originally Posted by Qarmaa
Hi. I'm working with a lot of HDTV material, so I need quickly spot the stereo and surround, then split and cut video according to sound. I have script written on python to process HDTV sources, but my workflow luck of batch process of splitting sound and writing trims for VapourSynth. Of course I can use bat command and parse log file of SplitAC3, but I prefer native way: rewriting for my needs on python.

So my question is: can you share sources of SplitAC3?
No problem. I have two versions:

SplitAc3 try to extract two streams (5.1 and 2.0) mixed in a invalid ac3 stream (TV capture for instance).
SpltAc3m try to extract multiple streams (5.1 and 2.0) mixed in a invalid ac3 stream (TV capture for instance).

Both are here
__________________
BeHappy, AviSynth audio transcoder.

Last edited by tebasuna51; 29th September 2021 at 16:38.
tebasuna51 is offline   Reply With Quote
Old 20th October 2018, 10:58   #17  |  Link
Qarmaa
Registered User
 
Join Date: Sep 2017
Posts: 5
Thank you, tebasuna51. I decided to modify your program a bit, and wrote simple script on python to parse output and extract trims for VapourSynth.

Code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

'''Detect HDTV's AC3 Cuts'''

import os
import sys
import re
import subprocess
import json
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from colorama import init, Fore, Style

ALLOWED_CONT = ('.mkv', '.mp4', '.ts', '.m2ts')

def split_ac3(audio_track, framerate):
    print(f'{Fore.MAGENTA}{Style.BRIGHT}Begin to run SplitAc3...')
    process = subprocess.run(['SplitAc3', audio_track, str(framerate)], check=True, universal_newlines=True, stdout=subprocess.PIPE)
    if process.returncode or 'written: 0 frames' in process.stdout:
        return

    print(process.stdout)
    return tuple((int(t[0]), int(t[1])) for t in re.findall(r"Trim\((\d+), (\d+)\)", process.stdout))

def main():
    init(autoreset=True)
    parser = ArgumentParser(description=__doc__, formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument('input', help='Source file')
    parser.add_argument('--fps', type=float, default=25.0)
    parser.add_argument('--no-junk', action='store_true', help='Remove junk')
    args = parser.parse_args()

    if not os.path.isfile(args.input):
        sys.exit(f'{Fore.RED}{Style.BRIGHT}File don\'t exists')

    source    = args.input
    framerate = args.fps

    if os.path.splitext(source)[-1].lower() in ALLOWED_CONT:
        probe_out = ['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', source]
        streams   = json.loads(subprocess.check_output(probe_out).decode())

        audio_streams = []
        for s in streams['streams']:
            if s['codec_type'] == 'audio':
                if s['codec_name'] == 'ac3':
                    audio_streams.append(s)

        if not audio_streams:
            sys.exit(f'{Fore.RED}{Style.BRIGHT}Source doesn\'t contain any Dolby Digital streams')

        audio_count = len(audio_streams)
        if audio_count == 1:
            print(f'{Fore.MAGENTA}{Style.BRIGHT}Source contains only one audio stream. Extracting...')
            audio_id = audio_streams[0]['index']
            extract_out = os.path.splitext(source)[0] + '.ac3'
        else:
            # Creating list for matching list index and audio index inside container
            for i, au_choice_stream in enumerate(audio_streams):
                au_choice_codec    = au_choice_stream['codec_name']
                au_choice_channels = au_choice_stream['channels']

                au_choice_lang = 'Und'
                if 'tags' in au_choice_stream and 'language' in au_choice_stream['tags']:
                    au_choice_lang = au_choice_stream['tags']['language']

                print(f'{i + 1}. {au_choice_lang}, {au_choice_channels} channel(s) (may be detected wrong)')

            choice_range = ', '.join(map(str, range(1, audio_count + 1)))
            while True:
                try:
                    audio_key = int(input('choice audio to use (number): '))
                    if audio_key <= 0 or audio_key > audio_count:
                        raise ValueError
                    break
                except ValueError:
                    print(f'{Fore.RED}{Style.BRIGHT}Wrong value. Possible values: {choice_range}')

            audio_id = audio_streams[audio_key - 1]['index']

        extract = subprocess.run(('ffmpeg', '-hide_banner', '-i', source, '-map', f'0:{audio_id}',
                                  '-c:a', 'copy', extract_out, '-y'), check=True)
        if extract.returncode:
            sys.exit(f'{Fore.RED}{Style.BRIGHT}Error occurred during extracting audio')
        else:
            trims_list = split_ac3(extract_out, framerate)
    elif os.path.splitext(source)[-1].lower() == '.ac3':
        trims_list = split_ac3(source, framerate)
    else:
        sys.exit(f'{Fore.RED}{Style.BRIGHT}Can hande only this formats: ' + ', '.join(ALLOWED_CONT) + ', .ac3 ')

    if trims_list:
        trims_log = os.path.splitext(source)[0] + '.trims.log'
        print(f'{Fore.YELLOW}{Style.BRIGHT}Mixed stream detected. Video trims logged.')
        with open(trims_log, 'w') as f:
            json.dump(trims_list, f)
    else:
        print(f'{Fore.GREEN}{Style.BRIGHT}No mixed stream detected')

    if args.no_junk:
        stereo = os.path.splitext(source)[0] + '2_0.ac3'
        if os.path.isfile(stereo):
            os.remove(stereo)
if __name__ == "__main__":
    main()
In VapourSynth I'm loading the trims if trims file exist and apply them on source:

Code:
ac3_trims = os.path.join(src_dir, feature_name, filename + '.trims.log')
if os.path.isfile(ac3_trims):
  with open(ac3_trims) as f:
    trims_list = json.load(f)
  source = core.std.Splice([core.std.Trim(source, first=f, last=l) for f, l in trims_list])
Attached Files
File Type: zip SplitAc3_v11c.zip (39.3 KB, 73 views)
Qarmaa is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 20:51.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.