Làm thế nào để bạn chỉnh sửa tạm dừng trong video YouTube?


9

Tôi đã nhận thấy trong một số video YouTube tạm dừng trong bài phát biểu đã bị cắt bỏ. Không có tạm dừng, và điều này làm cho video dễ xem hơn.

Làm thế nào được thực hiện? Tôi đã tìm kiếm cái này, nhưng chỉ tìm thấy hướng dẫn về cách làm thủ công, nhưng phải có cách tự động cho video YouTube, tôi hy vọng!

Đây là một ví dụ về một trong những video này:


2
Tôi đã làm video trên YouTube từ năm 2006 và tôi đã cắt các đoạn tạm dừng trong video của mình. Tôi chưa bao giờ nghe nói về một cách tự động để làm điều đó! Tuy nhiên, phần mềm chỉnh sửa video của bạn (như iMovie hoặc Premiere) có thể hiển thị bản nhạc âm thanh dưới dạng sóng âm thanh hiển thị trên màn hình. Tôi tìm kiếm những điểm khi nó "im lặng", và cắt chúng ra. Vâng, đó là một quy trình thủ công, nhưng việc xem sóng âm thanh trong bản âm thanh sẽ dễ dàng và nhanh chóng hơn là nghe phần mở đầu và kết thúc của mọi điều tôi đã nói trong video.
BrettFromLA

Tôi cũng không biết một cách tự động để làm điều này. Hãy nhớ rằng bất kỳ phương thức tự động nào, nếu nó tồn tại, sẽ không thể phân biệt mệnh đề giữa tạm dừng với tạm dừng giữa, giả sử, hai câu. Vì vậy, bạn sẽ phải quét kết quả theo cách thủ công, đánh bại mục đích.
Gyan

@BrettFromLA Có một cách, tôi đã đọc về nó trước đây, chỉ không thể nhớ chương trình.

Tôi có cùng một câu hỏi và nó liên quan đến 2 câu hỏi khác: superuser.com/questions/990357/iêu
Ryan

Câu trả lời:


5

Hiệu ứng mà bạn đang nói đến được gọi là jumpcut và nó đặc biệt phổ biến trong giới vlogger.
Theo như tôi biết, không có cách nào tự động để làm điều đó mặc dù có lẽ có thể làm được từ góc độ công nghệ. Tuy nhiên, sử dụng jumpcut có một số chức năng.

Bạn thoát khỏi sự im lặng và siết chặt càng nhiều thông tin ở dạng ngắn càng tốt, khiến người xem chú ý.
Chức năng quan trọng thứ hai là lựa chọn các bức ảnh của bạn. Trong khi xem qua tài liệu của bạn (thường được quay trong một lần), bạn có thể loại bỏ những thứ bạn không muốn (ngay cả khi bạn đang nói chuyện tại thời điểm đó) và thay đổi về cơ bản âm thanh của video.

Điều khiển sáng tạo gia tăng này đáng để xem xét rằng việc chỉnh sửa video của bạn theo cách thủ công theo cách này rất dễ dàng và sẽ không mất nhiều thời gian hoặc công sức.


tl; dr
Có thể thực hiện được, nhưng hiện tại không có giải pháp thân thiện với người dùng. Dù sao, tôi sẽ đề nghị làm bằng tay vì nhiều lý do được mô tả trong câu trả lời đầy đủ.


4

Bạn đang bị mất điểm. Anh ấy không cắt bỏ sự im lặng, anh ấy đang giữ một tốc độ bận rộn tốt, làm cho nó khó để tắt trong khi xem.

Làm thủ công. Tại sao?

  • Kể một câu chuyện, vì vậy bạn cần biết phần nào có liên quan và phần nào không

  • Đôi khi, mặc dù có những phần im lặng, có những thứ trực quan khác đang diễn ra, như cử chỉ hoang dã, khuôn mặt hài hước, tạm dừng để tạo hiệu ứng kịch tính.

  • Đôi khi các vết cắt của bạn KHÔNG theo thứ tự thời gian. Để làm cho câu chuyện hay hơn, bạn có thể chọn clip hoặc thêm clip từ dòng thời gian hoặc video hoàn toàn khác.

Vấn đề chính bạn sẽ tìm thấy là "số lần nhấp" của bạn ở đây khi bạn thực hiện các bước nhảy. Thông thường bạn hủy liên kết âm thanh và video và bạn CHỈ chuyển phần âm thanh.

Mong rằng sẽ giúp. Chúc mừng cắt.


2

Trên Avid ProTools khi bạn đang làm việc trên một video có đoạn âm thanh, có một số phím nóng để tự động chọn tất cả các phần âm thanh mà dạng sóng chuyển sang 0 hoặc gần với nó.

Việc mở rộng vùng chọn cũng cho đoạn video và cắt nó đi cũng nên thực hiện thủ thuật, sau đó bạn chỉ cần sử dụng một phím nóng khác để nối các phần bị cắt với nhau mà không tạm dừng ở giữa.

Tôi nghĩ rằng quy trình công việc này có thể được áp dụng trên hầu hết tất cả các NLE (trình soạn thảo phi tuyến tính) có sẵn xung quanh.



1

Khi bạn xóa im lặng (thời gian để thở, phản hồi, tạm dừng khó xử), cứ mỗi giờ diễn ra, là 10 phút không khí chết. Âm thanh không có gì.

Sự chú ý đã khó ... bạn nói ở 120 WPM. Bộ não của bạn có thể xử lý 400. Trong không gian trống là nơi bộ não của bạn bị phân tâm.

Tôi sử dụng phần mềm máy tính để bàn cho MAC hoặc PC để tự động loại bỏ không khí / im lặng khỏi Tệp MP4 & MP3. Nhìn vào biểu đồ, đặt mức âm thanh và thời gian phân chia, nhấn chạy. Việc cắt giảm được tự động hóa và được biên dịch lại thành một tệp MP4 hoặc MP3. Xem TimeBolt.io

nhập mô tả hình ảnh ở đây

Từ chối trách nhiệm Tôi sở hữu công cụ này.


Sản phẩm thú vị, xin chúc mừng.
Rafael

Cảm ơn bạn @Rafael
Doug Wulff

0

https://github.com/carykh/jumpcutter (giấy phép MIT) tự động xóa các phần của video không có hoặc có ít âm thanh. Nó dựa vào ffmpeg và đường ống được mã hóa trong Python 3.

Giải trình:

Kịch bản (giấy phép MIT, tác giả: carykh ):

from contextlib import closing
from PIL import Image
import subprocess
from audiotsm import phasevocoder
from audiotsm.io.wav import WavReader, WavWriter
from scipy.io import wavfile
import numpy as np
import re
import math
from shutil import copyfile, rmtree
import os
import argparse
from pytube import YouTube

def downloadFile(url):
    name = YouTube(url).streams.first().download()
    newname = name.replace(' ','_')
    os.rename(name,newname)
    return newname

def getMaxVolume(s):
    maxv = float(np.max(s))
    minv = float(np.min(s))
    return max(maxv,-minv)

def copyFrame(inputFrame,outputFrame):
    src = TEMP_FOLDER+"/frame{:06d}".format(inputFrame+1)+".jpg"
    dst = TEMP_FOLDER+"/newFrame{:06d}".format(outputFrame+1)+".jpg"
    if not os.path.isfile(src):
        return False
    copyfile(src, dst)
    if outputFrame%20 == 19:
        print(str(outputFrame+1)+" time-altered frames saved.")
    return True

def inputToOutputFilename(filename):
    dotIndex = filename.rfind(".")
    return filename[:dotIndex]+"_ALTERED"+filename[dotIndex:]

def createPath(s):
    #assert (not os.path.exists(s)), "The filepath "+s+" already exists. Don't want to overwrite it. Aborting."

    try:  
        os.mkdir(s)
    except OSError:  
        assert False, "Creation of the directory %s failed. (The TEMP folder may already exist. Delete or rename it, and try again.)"

def deletePath(s): # Dangerous! Watch out!
    try:  
        rmtree(s,ignore_errors=False)
    except OSError:  
        print ("Deletion of the directory %s failed" % s)
        print(OSError)

parser = argparse.ArgumentParser(description='Modifies a video file to play at different speeds when there is sound vs. silence.')
parser.add_argument('--input_file', type=str,  help='the video file you want modified')
parser.add_argument('--url', type=str, help='A youtube url to download and process')
parser.add_argument('--output_file', type=str, default="", help="the output file. (optional. if not included, it'll just modify the input file name)")
parser.add_argument('--silent_threshold', type=float, default=0.03, help="the volume amount that frames' audio needs to surpass to be consider \"sounded\". It ranges from 0 (silence) to 1 (max volume)")
parser.add_argument('--sounded_speed', type=float, default=1.00, help="the speed that sounded (spoken) frames should be played at. Typically 1.")
parser.add_argument('--silent_speed', type=float, default=5.00, help="the speed that silent frames should be played at. 999999 for jumpcutting.")
parser.add_argument('--frame_margin', type=float, default=1, help="some silent frames adjacent to sounded frames are included to provide context. How many frames on either the side of speech should be included? That's this variable.")
parser.add_argument('--sample_rate', type=float, default=44100, help="sample rate of the input and output videos")
parser.add_argument('--frame_rate', type=float, default=30, help="frame rate of the input and output videos. optional... I try to find it out myself, but it doesn't always work.")
parser.add_argument('--frame_quality', type=int, default=3, help="quality of frames to be extracted from input video. 1 is highest, 31 is lowest, 3 is the default.")

args = parser.parse_args()



frameRate = args.frame_rate
SAMPLE_RATE = args.sample_rate
SILENT_THRESHOLD = args.silent_threshold
FRAME_SPREADAGE = args.frame_margin
NEW_SPEED = [args.silent_speed, args.sounded_speed]
if args.url != None:
    INPUT_FILE = downloadFile(args.url)
else:
    INPUT_FILE = args.input_file
URL = args.url
FRAME_QUALITY = args.frame_quality

assert INPUT_FILE != None , "why u put no input file, that dum"

if len(args.output_file) >= 1:
    OUTPUT_FILE = args.output_file
else:
    OUTPUT_FILE = inputToOutputFilename(INPUT_FILE)

TEMP_FOLDER = "TEMP"
AUDIO_FADE_ENVELOPE_SIZE = 400 # smooth out transitiion's audio by quickly fading in/out (arbitrary magic number whatever)

createPath(TEMP_FOLDER)

command = "ffmpeg -i "+INPUT_FILE+" -qscale:v "+str(FRAME_QUALITY)+" "+TEMP_FOLDER+"/frame%06d.jpg -hide_banner"
subprocess.call(command, shell=True)

command = "ffmpeg -i "+INPUT_FILE+" -ab 160k -ac 2 -ar "+str(SAMPLE_RATE)+" -vn "+TEMP_FOLDER+"/audio.wav"

subprocess.call(command, shell=True)

command = "ffmpeg -i "+TEMP_FOLDER+"/input.mp4 2>&1"
f = open(TEMP_FOLDER+"/params.txt", "w")
subprocess.call(command, shell=True, stdout=f)



sampleRate, audioData = wavfile.read(TEMP_FOLDER+"/audio.wav")
audioSampleCount = audioData.shape[0]
maxAudioVolume = getMaxVolume(audioData)

f = open(TEMP_FOLDER+"/params.txt", 'r+')
pre_params = f.read()
f.close()
params = pre_params.split('\n')
for line in params:
    m = re.search('Stream #.*Video.* ([0-9]*) fps',line)
    if m is not None:
        frameRate = float(m.group(1))

samplesPerFrame = sampleRate/frameRate

audioFrameCount = int(math.ceil(audioSampleCount/samplesPerFrame))

hasLoudAudio = np.zeros((audioFrameCount))



for i in range(audioFrameCount):
    start = int(i*samplesPerFrame)
    end = min(int((i+1)*samplesPerFrame),audioSampleCount)
    audiochunks = audioData[start:end]
    maxchunksVolume = float(getMaxVolume(audiochunks))/maxAudioVolume
    if maxchunksVolume >= SILENT_THRESHOLD:
        hasLoudAudio[i] = 1

chunks = [[0,0,0]]
shouldIncludeFrame = np.zeros((audioFrameCount))
for i in range(audioFrameCount):
    start = int(max(0,i-FRAME_SPREADAGE))
    end = int(min(audioFrameCount,i+1+FRAME_SPREADAGE))
    shouldIncludeFrame[i] = np.max(hasLoudAudio[start:end])
    if (i >= 1 and shouldIncludeFrame[i] != shouldIncludeFrame[i-1]): # Did we flip?
        chunks.append([chunks[-1][1],i,shouldIncludeFrame[i-1]])

chunks.append([chunks[-1][1],audioFrameCount,shouldIncludeFrame[i-1]])
chunks = chunks[1:]

outputAudioData = np.zeros((0,audioData.shape[1]))
outputPointer = 0

lastExistingFrame = None
for chunk in chunks:
    audioChunk = audioData[int(chunk[0]*samplesPerFrame):int(chunk[1]*samplesPerFrame)]

    sFile = TEMP_FOLDER+"/tempStart.wav"
    eFile = TEMP_FOLDER+"/tempEnd.wav"
    wavfile.write(sFile,SAMPLE_RATE,audioChunk)
    with WavReader(sFile) as reader:
        with WavWriter(eFile, reader.channels, reader.samplerate) as writer:
            tsm = phasevocoder(reader.channels, speed=NEW_SPEED[int(chunk[2])])
            tsm.run(reader, writer)
    _, alteredAudioData = wavfile.read(eFile)
    leng = alteredAudioData.shape[0]
    endPointer = outputPointer+leng
    outputAudioData = np.concatenate((outputAudioData,alteredAudioData/maxAudioVolume))

    #outputAudioData[outputPointer:endPointer] = alteredAudioData/maxAudioVolume

    # smooth out transitiion's audio by quickly fading in/out

    if leng < AUDIO_FADE_ENVELOPE_SIZE:
        outputAudioData[outputPointer:endPointer] = 0 # audio is less than 0.01 sec, let's just remove it.
    else:
        premask = np.arange(AUDIO_FADE_ENVELOPE_SIZE)/AUDIO_FADE_ENVELOPE_SIZE
        mask = np.repeat(premask[:, np.newaxis],2,axis=1) # make the fade-envelope mask stereo
        outputAudioData[outputPointer:outputPointer+AUDIO_FADE_ENVELOPE_SIZE] *= mask
        outputAudioData[endPointer-AUDIO_FADE_ENVELOPE_SIZE:endPointer] *= 1-mask

    startOutputFrame = int(math.ceil(outputPointer/samplesPerFrame))
    endOutputFrame = int(math.ceil(endPointer/samplesPerFrame))
    for outputFrame in range(startOutputFrame, endOutputFrame):
        inputFrame = int(chunk[0]+NEW_SPEED[int(chunk[2])]*(outputFrame-startOutputFrame))
        didItWork = copyFrame(inputFrame,outputFrame)
        if didItWork:
            lastExistingFrame = inputFrame
        else:
            copyFrame(lastExistingFrame,outputFrame)

    outputPointer = endPointer

wavfile.write(TEMP_FOLDER+"/audioNew.wav",SAMPLE_RATE,outputAudioData)

'''
outputFrame = math.ceil(outputPointer/samplesPerFrame)
for endGap in range(outputFrame,audioFrameCount):
    copyFrame(int(audioSampleCount/samplesPerFrame)-1,endGap)
'''

command = "ffmpeg -framerate "+str(frameRate)+" -i "+TEMP_FOLDER+"/newFrame%06d.jpg -i "+TEMP_FOLDER+"/audioNew.wav -strict -2 "+OUTPUT_FILE
subprocess.call(command, shell=True)

deletePath(TEMP_FOLDER)

0

Bạn có thể sử dụng tập lệnh người dùng tạm dừng vụng về cho Adobe After Effects. Chi phí của tập lệnh người dùng: 59,99 USD

Ảnh chụp màn hình:

nhập mô tả hình ảnh ở đây

Bản giới thiệu:

Tuyên bố miễn trừ trách nhiệm: tại thời điểm tôi viết bài đăng này (2019-06-08), tôi làm việc cho Adobe.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.