এমপিইজি ভিডিওটি 10 ​​মিনিটের অংশে বিভক্ত করতে আমি কীভাবে ffmpeg ব্যবহার করতে পারি?


62

অনলাইনে বড় বড় ভিডিও বিভাগ প্রকাশ করার জন্য প্রায়শই ওপেন সোর্স বা সক্রিয় বিকাশকারী সম্প্রদায়ের প্রয়োজন হয়। (মিট-আপ ভিডিও, ক্যাম্পআউটস, প্রযুক্তিগত আলাপ ...) আমি একজন বিকাশকারী এবং একজন ভিডিওগ্রাফার না হওয়ার কারণে প্রিমিয়াম ভিমেও অ্যাকাউন্টে অতিরিক্ত স্ক্র্যাচ বের করার কোনও ইচ্ছা আমার নেই। তারপরে আমি কীভাবে একটি 12.5 গিগাবাইট (1:20:00) এমপিইজি টেক টক ভিডিওটি নেব এবং এটিকে ভাগ করে নেব? ভিডিও ভাগ করে নেওয়ার সাইটগুলিতে সহজেই আপলোড করার জন্য বিভাগগুলিতে?


নতুন ট্যাগগুলি সমন্বিত করার জন্য @ স্টিভেনডিকে বিশেষ ধন্যবাদ।
গ্যাব্রিয়েল

উত্তর:


69
$ ffmpeg -i source-file.foo -ss 0 -t 600 first-10-min.m4v
$ ffmpeg -i source-file.foo -ss 600 -t 600 second-10-min.m4v
$ ffmpeg -i source-file.foo -ss 1200 -t 600 third-10-min.m4v
...

এটি একটি লুপে করতে স্ক্রিপ্টের মধ্যে মোড়ানো শক্ত হবে না।

সাবধানতা অবলম্বন করুন যদি আপনি কোনও ffprobeকল থেকে সময়কাল আউটপুটের ভিত্তিতে পুনরাবৃত্তির সংখ্যা গণনা করার চেষ্টা করেন যে আপনি ক্লিপটির শুরুতে গড় বিট রেট এবং ক্লিপের ফাইলের আকার থেকে অনুমান করা হয় যদি আপনি -count_framesযুক্তি না দেন, যা এর কাজটি যথেষ্ট গতিতে করে দেয় s ।

আরেকটি বিষয় সম্পর্কে সচেতন হতে হবে হ'ল -ssকমান্ড লাইনের বিকল্পের অবস্থানটি গুরুত্বপূর্ণ । আমার এখন এটি কোথায় ধীর তবে সঠিক। এই উত্তরের প্রথম সংস্করণটি দ্রুত কিন্তু অসম্পূর্ণ বিকল্প দিয়েছে। সংযুক্ত নিবন্ধটি বেশিরভাগ-দ্রুত-তবে-তবুও নির্ভুল বিকল্পের বর্ণনা দেয়, যার জন্য আপনি কিছুটা জটিলতার জন্য অর্থ প্রদান করেন।

সব কিছু বাদ দিয়ে, আমি মনে করি না আপনি প্রতিটি ক্লিপের জন্য সঠিকভাবে 10 মিনিটে কাটতে চান। এটি বাক্যগুলি এমনকি শব্দের মাঝখানেই কাট ফেলবে। আমি মনে করি আপনার 10 মিনিটের ব্যবধানে লজ্জাজনক প্রাকৃতিক কাট পয়েন্টগুলি পেতে কোনও ভিডিও সম্পাদক বা প্লেয়ার ব্যবহার করা উচিত।

ধরে নিচ্ছি আপনার ফাইলটি এমন ফর্ম্যাটে রয়েছে যা ইউটিউব সরাসরি গ্রহণ করতে পারে, বিভাগগুলি পেতে আপনাকে পুনরায় কোডিং করতে হবে না। ffmpeg"অনুলিপি" কোডেক ব্যবহার করে আউটচুড থেকে এনকোডড এ / ভি পাস করার জন্য এটিকে কেবল প্রাকৃতিক কাটা পয়েন্ট অফসেটগুলি পাস করুন:

$ ffmpeg -i source.m4v -ss 0 -t 593.3 -c copy part1.m4v
$ ffmpeg -i source.m4v -ss 593.3 -t 551.64 -c copy part2.m4v
$ ffmpeg -i source.m4v -ss 1144.94 -t 581.25 -c copy part3.m4v
...

-c copyযুক্তি বলা হয়েছে যে সব হিসাবে হয় আউটপুট মধ্যে সমস্ত ইনপুট স্ট্রিম (অডিও, ভিডিও, এবং সম্ভাব্য যেমন সাবটাইটেল অন্যদের,) কপি করতে। সাধারণ এ / ভি প্রোগ্রামগুলির জন্য, এটি আরও ভার্বোজ পতাকা -c:v copy -c:a copyবা পুরানো স্টাইলের পতাকাগুলির সমতুল্য -vcodec copy -acodec copy। আপনি যখন কেবলমাত্র একটি স্ট্রিমের অনুলিপি করতে চান তবে আপনি আরও ভার্বোস স্টাইল ব্যবহার করবেন তবে অন্যটিকে পুনরায় এনকোড করুন। উদাহরণস্বরূপ, বহু বছর আগে এইচ .২64৪ ভিডিওর সাহায্যে ভিডিও সংকোচনের জন্য কুইকটাইম ফাইলগুলির সাথে একটি প্রচলিত অনুশীলন ছিল তবে অডিওটিকে সঙ্কুচিত পিসিএম হিসাবে ছেড়ে যান ; আপনি যদি আজ এইরকম একটি ফাইল জুড়ে দৌড়ান, আপনি -c:v copy -c:a aacভিডিওটি অবাঞ্ছিত রেখে কেবল অডিও স্ট্রিমটিকে পুনরায় প্রসেস করার জন্য এটিকে আধুনিকীকরণ করতে পারেন ।

প্রথমটির পরে উপরের প্রতিটি কমান্ডের সূচনা পয়েন্ট হ'ল পূর্ববর্তী কমান্ডের প্রারম্ভ পয়েন্ট এবং পূর্ববর্তী আদেশের সময়কাল's


1
"প্রতিটি ক্লিপের জন্য ঠিক 10 মিনিটে কাটা" একটি ভাল পয়েন্ট।
ক্রিস

হতে পারে-شو_পকেটস প্যারাম ব্যবহার করে আপনি এটিকে আরও সঠিক করে তুলতে পারেন।
রজারডপ্যাক

কিভাবে একটি লুপ উপর রাখা?
কেরাজী আর

আমি এই সেন্টিমিডি ইয়াটি ব্যবহার করুন এটি ডানদিকে বিভক্ত হয়ে গেছে তবে এখন ভিডিও এবং অডিও এসওয়াইএনসিতে নেই কোনও সাহায্য
সুনীল চৌধুরী চৌধুরী

@ সুনিলচৌধারি: এ / ভি ফাইল ফর্ম্যাটগুলি জটিল এবং সমস্ত সফ্টওয়্যার সেগুলি একইভাবে প্রয়োগ করে না, যাতে ffmpegঅডিও এবং ভিডিও স্ট্রিমের মধ্যে তথ্য সমন্বয় বজায় রাখা প্রয়োজন উত্স ফাইলে উপস্থিত নাও হতে পারে। যদি এটি আপনার হয়ে থাকে তবে বিভাজনের আরও জটিল পদ্ধতি রয়েছে যা সমস্যা এড়ায়।
ওয়ারেন ইয়ং

52

এখানে একটি লাইন সমাধান :

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:20:00 -f segment output%03d.mp4

দয়া করে নোট করুন যে এটি আপনাকে সঠিক বিভাজন দেয় না, তবে আপনার প্রয়োজনের সাথে মাপসই করা উচিত। এটি উল্লিখিত সময়ের পরে প্রথম ফ্রেমে কাটা হবে segment_time, উপরের কোডে এটি 20 মিনিটের চিহ্নের পরে হবে।

যদি আপনি দেখতে পান যে কেবল প্রথম খণ্ডটি খেলতে পারা -reset_timestamps 1যায় তবে মন্তব্যে উল্লিখিত হিসাবে যুক্ত করার চেষ্টা করুন ।

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:20:00 -f segment -reset_timestamps 1 output%03d.mp4

2
যদি আপনি ভিডিওর মানকে মূল্য দেন তবে এটি আপনাকে খুব নির্ভুল স্প্লিট দেয় । নির্দিষ্ট সময়ের উপর ভিত্তি করে বিভক্ত হওয়ার চেয়ে অনুরোধকৃত সময়টি অনুসরণ করে নিকটতম কীফ্রেমে বিভক্ত হয়, সুতরাং প্রতিটি নতুন বিভাগ সর্বদা একটি কীফ্রেম দিয়ে শুরু হয়।
মালভাইনাস

3
ইউনিট কি? 8s? 8min? 8h?
ব্যবহারকারী 1133275

1
@ ব্যবহারকারী 1133275 এর দ্বিতীয়
জন

2
ম্যাক এ, আমি দেখতে পেলাম যে এর ফলাফল এন আউটপুট ভিডিও খণ্ডে ঘটেছে তবে তাদের মধ্যে ১ ম 1 টিই একটি বৈধ, দেখার যোগ্য এমপি 4 ছিল। অন্যান্য এন -1 অংশগুলি অডিও ছাড়া খালি ভিডিও (সমস্ত কালো) ছিল। এটি কাজ করতে, আমাকে পুনরায় সেট_টাইম স্ট্যাম্পস পতাকাটি যুক্ত করতে হবে: ffmpeg -i ইনপুট। এমপি 4 -c কপি-ম্যাপ 0-সেগমেন্ট_টাইম 8 -f বিভাগ-পুনর্নির্মাণ_টাইম স্ট্যাম্পস 1 আউটপুট% 03d.mp4।
জারমড

3
পাওয়া গেছে যে -reset_timestamps 1আমার জন্য সমস্যা সমাধান করে
জালার্সছ

6

এর আগেও একই সমস্যার মুখোমুখি হয়েছিলেন এবং এটি করার জন্য একটি সাধারণ পাইথন স্ক্রিপ্ট একসাথে রেখেছিলেন (FFMpeg ব্যবহার করে)। এখানে উপলভ্য: https://github.com/c0decracker/video-splitter , এবং নীচে আটকানো:

#!/usr/bin/env python
import subprocess
import re
import math
from optparse import OptionParser
length_regexp = 'Duration: (\d{2}):(\d{2}):(\d{2})\.\d+,'
re_length = re.compile(length_regexp)
def main():
    (filename, split_length) = parse_options()
    if split_length <= 0:
        print "Split length can't be 0"
        raise SystemExit
    output = subprocess.Popen("ffmpeg -i '"+filename+"' 2>&1 | grep 'Duration'",
                              shell = True,
                              stdout = subprocess.PIPE
    ).stdout.read()
    print output
    matches = re_length.search(output)
    if matches:
        video_length = int(matches.group(1)) * 3600 + \
                       int(matches.group(2)) * 60 + \
                       int(matches.group(3))
        print "Video length in seconds: "+str(video_length)
    else:
        print "Can't determine video length."
        raise SystemExit
    split_count = int(math.ceil(video_length/float(split_length)))
    if(split_count == 1):
        print "Video length is less then the target split length."
        raise SystemExit
    split_cmd = "ffmpeg -i '"+filename+"' -vcodec copy "
    for n in range(0, split_count):
        split_str = ""
        if n == 0:
            split_start = 0
        else:
            split_start = split_length * n
            split_str += " -ss "+str(split_start)+" -t "+str(split_length) + \
                         " '"+filename[:-4] + "-" + str(n) + "." + filename[-3:] + \
                         "'"
    print "About to run: "+split_cmd+split_str
    output = subprocess.Popen(split_cmd+split_str, shell = True, stdout =
                              subprocess.PIPE).stdout.read()
def parse_options():
    parser = OptionParser()
    parser.add_option("-f", "--file",
                      dest = "filename",
                      help = "file to split, for example sample.avi",
                      type = "string",
                      action = "store"
    )
    parser.add_option("-s", "--split-size",
                      dest = "split_size",
                      help = "split or chunk size in seconds, for example 10",
                      type = "int",
                      action = "store"
    )
    (options, args) = parser.parse_args()
    if options.filename and options.split_size:
        return (options.filename, options.split_size)
    else:
        parser.print_help()
        raise SystemExit
if __name__ == '__main__':
    try:
        main()
    except Exception, e:
        print "Exception occured running main():"
        print str(e)

1
পরবর্তী সময় একটি মন্তব্য করুন। লিংক-কেবল উত্তরগুলি এখানে সত্যই পছন্দ হয় না এবং আপনি যদি নিজের সাইটের বিজ্ঞাপন দেন তবে একই। যদি এটি সোর্স কোড সহ একটি ওপেনসোর্স প্রকল্প হয়, তবে এটি ব্যতিক্রম হতে পারে তবে আমি এখন আপনার উত্তর সরানোর পক্ষে ভোট না দিয়ে আমার পর্যালোচনা সুযোগগুলি ঝুঁকির মধ্যে ফেলেছি । এবং হ্যাঁ, আপনি মন্তব্য পোস্ট করতে পারবেন না, তবে আপনি 5 টি upvotes সংগ্রহ করার পরে (যা আপনার ক্ষেত্রে খুব দ্রুত বলে মনে হচ্ছে) আপনি পাবেন।
ব্যবহারকারী 259412

2
হাই এবং সাইটে আপনাকে স্বাগতম। শুধুমাত্র উত্তর লিঙ্ক পোস্ট করবেন না। আপনার স্ক্রিপ্ট নিজেই সম্ভবত দুর্দান্ত উত্তর দেবে, তবে এর লিঙ্কটি কোনও উত্তর নয়। এটি একটি উত্তরের দিকে নির্দেশ করে একটি সাইনপোস্ট । যে আরও এখানে । যেহেতু আপনি দয়া করে লিঙ্কটি দিয়েছেন তাই আমি এগিয়ে গিয়ে স্ক্রিপ্টটি আপনার উত্তরটির শিরোনামে অন্তর্ভুক্ত করেছি। যদি আপনি তাতে আপত্তি করেন তবে দয়া করে উত্তরটি পুরোপুরি মুছুন।
টেরডন

3

বিকল্প বিন্যাসের সঠিক বিরামচিহ্নটি নোট করুন -ss mm:ss.xxx। আমি স্বজ্ঞাত কিন্তু-ভুল ব্যবহার করার চেষ্টা ঘণ্টা লড়াই mm:ss:xxকোন উপকার।

$ man ffmpeg | grep -C1 position

-এস পজিশন
সেকেন্ডে নির্দিষ্ট সময় অবস্থানের সন্ধান করুন। "এইচএইচ: মিমি: এসএস [.xxx]" সিনট্যাক্সটিও সমর্থিত।

এখানে এবং এখানে উল্লেখ ।


3

আপনি যদি সত্যিই একই অংশ তৈরি করতে চান তবে প্রতিটি অংশের প্রথম ফ্রেমে আইফ্রেম তৈরি করতে ffmpeg কে অবশ্যই বাধ্য করতে হবে যাতে আপনি এই কমান্ডটি 0.5 সেকেন্ড অংশ তৈরির জন্য ব্যবহার করতে পারেন।

ffmpeg -hide_banner  -err_detect ignore_err -i input.mp4 -r 24 -codec:v libx264  -vsync 1  -codec:a aac  -ac 2  -ar 48k  -f segment   -preset fast  -segment_format mpegts  -segment_time 0.5 -force_key_frames  "expr: gte(t, n_forced * 0.5)" out%d.mkv

এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। সাথী ভাগ করে নেওয়ার জন্য ধন্যবাদ!
স্টিফান আহল্ফ

3

একটি বিকল্প আরও পঠনযোগ্য উপায় হবে

ffmpeg -i input.mp4 -ss 00:00:00 -to 00:10:00 -c copy output1.mp4
ffmpeg -i input.mp4 -ss 00:10:00 -to 00:20:00 -c copy output2.mp4

/**
* -i  input file
* -ss start time in seconds or in hh:mm:ss
* -to end time in seconds or in hh:mm:ss
* -c codec to use
*/

এখানে সাধারণভাবে ব্যবহৃত FFmpeg কমান্ডগুলির উত্স এবং তালিকা রয়েছে।


0
#!/bin/bash

if [ "X$1" == "X" ]; then
    echo "No file name for split, exiting ..."
    exit 1
fi

if [ ! -f "$1" ]; then
    echo "The file '$1' doesn't exist. exiting ..."
    exit 1
fi

duration=$(ffmpeg -i "$1" 2>&1 | grep Duration | sed 's/^.*Duration: \(.*\)\..., start.*$/\1/' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')      #'
split_time=${split_time:-55}
time=0
part=1

filename=${file%%.*}
postfix=${file##*.}

while [ ${time} -le ${duration} ]; do

echo    ffmpeg -i "$1" -vcodec copy -ss ${time} -t ${split_time} "${filename}-${part}.${postfix}"
    (( part++ ))
    (( time = time + split_time ))

done

0

ঠিক এটি করতে ffmpeg এর মধ্যে যা তৈরি করা হয়েছে তা ব্যবহার করুন use

ffmpeg -i invid.mp4 -threads 3 -vcodec copy -f segment -segment_time 2 cam_out_h264%04d.mp4

এটি এটিকে মোটামুটি 2 সেকেন্ড চাকগুলিতে ভাগ করবে, প্রাসঙ্গিক কীফ্রেমে বিভক্ত হবে এবং cam_out_h2640001.mp4, cam_out_h2640002.mp4, ইত্যাদি ফাইলগুলিতে আউটপুট দেবে etc.


নিশ্চিত নয় যে আমি বুঝতে পেরেছি কেন এই উত্তরটি নিচে ভোট দেওয়া হয়েছে। এটা ভালো কাজ করবে বলে মনে হয়।
কস্টিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.