ฉันจะแบ่งไฟล์เสียงเป็นหลายไฟล์ได้อย่างไร


35

ฉันพบบางอย่างสำหรับวิดีโอซึ่งมีลักษณะเช่นนี้

ffmpeg -i * -c:v libx264 -crf 22 -map 0 -segment_time 1 -g 1 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*9)" -f segment output%03d.mp4

ฉันพยายามใช้ไฟล์เสียงนั้น แต่ไฟล์เสียงแรกเท่านั้นที่มีไฟล์เสียงจริงไฟล์อื่น ๆ เงียบกว่านั้นดีมากมันสร้างไฟล์เสียงใหม่ทุกวินาที ไม่มีใครรู้ว่าสิ่งที่จะแก้ไขเพื่อให้งานนี้กับไฟล์เสียงหรือคำสั่งอื่นที่สามารถทำเช่นเดียวกัน?


หากคุณต้องการวิธีการอื่นในการทำเช่นนี้โปรดอธิบายรายละเอียดเพิ่มเติมว่าคุณกำลังพยายามทำอะไร ffmpeg cmdlines จดจำได้ยาก

1
@siblynx ตามที่ฉันอธิบายในคำถามให้แบ่งทุก ๆ วินาทีของไฟล์เสียงเป็นไฟล์เสียงใหม่
DisplayName

คำตอบ:


51

สิ่งนี้ใช้ได้กับฉันเมื่อฉันลองใช้ไฟล์ MP3

$ ffmpeg -i somefile.mp3 -f segment -segment_time 3 -c copy out%03d.mp3

ที่ไหน-segment_timeเป็นจำนวนเวลาที่คุณต้องการต่อแต่ละไฟล์ (เป็นวินาที)

อ้างอิง


ทำงานบนmp3 s ล้มเหลวในการฉันพูดm4bว่า "ออดิโอสตรีมไม่ถูกต้องต้องมีออดิโอสตรีม MP3 หนึ่งตัว"
vossad01

FYI แทนที่mp3ด้วยm4a
Mikhail

มีกรณีใดบ้างที่ฉันมีไฟล์ 40 นาทีที่ฉันอยากจะพูดว่า 4min, 6min, 12min, 8min, 10 นาทีแทนที่จะแยกย่อยเป็นไฟล์ย่อยเหมือนกัน?
isosceleswheel เมื่อ

@isosceleswheel - ใช้เวลาดูที่นี้ - unix.stackexchange.com/questions/94168/...
slm

มันยังใช้งานได้กับไฟล์ wav
Mário Meyrelles

19

หากต้องการแยกไฟล์เสียงขนาดใหญ่เป็นชุดแทร็กที่มีความยาวต่างกันคุณสามารถใช้คำสั่งต่อไปนี้:

# -to is the end time of the sub-file
ffmpeg -i BIG_FILE -acodec copy -ss START_TIME -to END_TIME LITTLE_FILE

ตัวอย่างเช่นฉันเลิก.. ไฟล์เดียวของ Inception Original Soundtrack เป็นไฟล์ย่อยโดยใช้ไฟล์ข้อความนี้ที่มีชื่อเริ่มต้นสิ้นสุดชื่อ:

00:00:00 00:01:11 01_half_remembered_dream
00:01:11 00:03:07 02_we_built_our_own_world
00:03:07 00:05:31 03_dream_is_collapsing
00:05:31 00:09:14 04_radical_notion
00:09:14 00:16:58 05_old_souls
00:16:58 00:19:22 06
00:19:22 00:24:16 07_mombasa
00:24:16 00:26:44 08_one_simple_idea
00:26:44 00:31:49 09_dream_within_a_dream
00:31:49 00:41:19 10_waiting_for_a_train
00:41:19 00:44:44 11_paradox
00:44:44 00:49:20 12_time

ฉันเขียนawkโปรแกรมสั้น ๆนี้เพื่ออ่านไฟล์ข้อความและสร้างffmpegคำสั่งจากแต่ละบรรทัด:

{
    # make ffmpeg command string using sprintf
    cmd = sprintf("ffmpeg -i inception_ost.opus -acodec copy -ss %s -to %s %s.opus", $1, $2, $3)

    # execute ffmpeg command with awk's system function
    system(cmd)
}

นี่คือโปรแกรมที่มีรายละเอียดเพิ่มเติมpythonที่เรียกว่าsplit.pyซึ่งตอนนี้ทั้งไฟล์แทร็กดั้งเดิมและไฟล์ข้อความที่ระบุแทร็กย่อยจะถูกอ่านจากบรรทัดคำสั่ง:

import subprocess
import sys


def main():
    """split a music track into specified sub-tracks by calling ffmpeg from the shell"""

    # check command line for original file and track list file
    if len(sys.argv) != 3:
        print 'usage: split <original_track> <track_list>'
        exit(1)

    # record command line args
    original_track = sys.argv[1]
    track_list = sys.argv[2]

    # create a template of the ffmpeg call in advance
    cmd_string = 'ffmpeg -i {tr} -acodec copy -ss {st} -to {en} {nm}.opus'

    # read each line of the track list and split into start, end, name
    with open(track_list, 'r') as f:
        for line in f:
            # skip comment and empty lines
            if line.startswith('#') or len(line) <= 1:
                continue

            # create command string for a given track
            start, end, name = line.strip().split()
            command = cmd_string.format(tr=original_track, st=start, en=end, nm=name)

            # use subprocess to execute the command in the shell
            subprocess.call(command, shell=True)

    return None


if __name__ == '__main__':
    main()

คุณสามารถสร้างการffmpegโทรที่ซับซ้อนมากขึ้นและง่ายขึ้นโดยการแก้ไขเทมเพลตคำสั่งและ / หรือเพิ่มฟิลด์เพิ่มเติมให้กับแต่ละบรรทัดของไฟล์ track_list


มันยอดเยี่ยมมาก! กรุณาบอกฉันวิธีการเรียกใช้จากโปรแกรมหลามคือฉันต้องการอ่านเสียงและไฟล์คำอธิบายประกอบที่มีเริ่มต้นสิ้นสุดฉลาก แล้วแยกเสียงออกเป็นชิ้น ๆ ด้วยขนาดที่สอดคล้องกับแต่ละบรรทัดในไฟล์
kRazzy R

2
@kRazzyR subprocess.call(command)เป็นpythonอะนาล็อกไปsystem(command)ในawkทั้งสองที่ช่วยให้คุณสามารถส่งffmpegคำสั่งเปลือก ฉันแก้ไขโพสต์ของฉันเพื่อรวมการpythonใช้งานที่ยืดหยุ่นซึ่งแสดงวิธีหนึ่งที่คุณสามารถทำได้
isosceleswheel

1
จากประสบการณ์ของฉันเวลาเริ่มต้นของแทร็ก # 2 ควรเท่ากับเวลาสิ้นสุดของแทร็ก # 1 และอื่น ๆ นั่นคือเวลาตัวอย่างของคุณจะข้ามหนึ่งวินาทีระหว่างแต่ละแทร็ก
ทิมสมิ ธ

1
นี่คือเวอร์ชั่น bash / zsh ขนาดกะทัดรัด แก้ไขเวลาตามต้องการจากนั้นลบคำecho เพื่อเรียกใช้คำสั่งจริง source="source audio file.m4a"; i=0; t1=0:00; for end_time in 1:24 5:40 14:48 19:33 35:11 40:00 46:08 51:58 ''; do i=$((i+1)); t0=$t1 t1=$end_time; echo ffmpeg -i "$source" -acodec copy -ss $t0 ${t1:+-to} $t1 $(printf "track%02d.%s" $i ${source##*.}); done
Tim Smith

@TimSmith ขอบคุณที่ติดตามฉันเพิ่มการแก้ไขข้างต้น อาจมีอาการสะอึกเล็ก ๆ ระหว่างแทร็กขึ้นอยู่กับผู้เล่นของคุณ แต่การทำเช่นนี้จะดีกว่าการตัด 1s
isosceleswheel

3

บรรทัดต่อไปนี้จะแบ่งไฟล์เสียงออกเป็นหลายไฟล์โดยแต่ละไฟล์มีระยะเวลา 30 วินาที

ffmpeg -i file.wav -f segment -segment_time 30 -c copy parts/output%09d.wav

เปลี่ยน 30 (ซึ่งคือจำนวนวินาที) เป็นหมายเลขใด ๆ ที่คุณต้องการ


1

คำตอบของ slm :

ffmpeg -i somefile.mp3  -f segment -segment_time 3 -c copy out%03d.mp3

จะไม่ทำงานสำหรับฉันโดยไม่-map 0เพิ่ม:

ffmpeg -i somefile.mp3 -map 0 -f segment -segment_time 3 -c copy out%03d.mp3

การทำแผนที่ใช้งานได้ดี แต่ยังเพิ่ม -vn เพื่อตัดภาพที่ฝังอยู่ออกหรือจะพยายามสร้างภาพใหม่สำหรับแต่ละส่วน (sloooowww)
Chris Reid

1

วิธีแก้ปัญหาที่ระบุไม่ได้ผลสำหรับฉัน ฉันเชื่อว่าสิ่งนี้จะเกิดจากffmpegระบบของฉันใน เวอร์ชันที่เก่ากว่า
ไม่ว่าในกรณีใดฉันต้องการเสนอวิธีแก้ปัญหาที่ใช้งานได้สำหรับฉัน นอกจากนี้คุณยังสามารถปรับแต่งตัวจับเวลาเพื่อให้สามารถซ้อนทับเสียงได้หากต้องการ

Output file #0 does not contain any stream

ffmpeg -i your_audio_file.mp3 -acodec copy -t 00:00:30 -ss 00:00:00 split_audio_file.mp3

แบ่งไฟล์เสียงของคุณออกเป็น 30 วินาที


คำถามใหม่จะเป็นไปตามนี้ไม่ตอบคำถามของ OP!
George Udosen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.