FFmpeg로 동영상이 필요없는 장면 삭제 ~ 장면 검출 및 썸네일 이미지 출력 ~
하고 싶은 일
FFmpeg를 사용하여 동영상에서 필요하지 않은 장면을 삭제합니다.
자신은 스포츠의 동영상 편집을 하는 경우가 많습니다만, 플레이에 관계없는 장면은, 작업전에 삭제해 두면 그 후의 편집이 편해집니다.
FFmpeg란?
동영상이나 음성을 변환·편집할 수 있는 프리의 오픈 소스 툴입니다.
커맨드 라인에서 사용하는 도구로 인해 어려울 수 있지만, 다기능 및 실행 속도가 빠르고 매우 강력한 동영상 편집 도구로 사용할 수 있습니다.
이번에는 FFmpeg의 다음 기능을 사용했습니다.
동영상이나 음성을 변환·편집할 수 있는 프리의 오픈 소스 툴입니다.
커맨드 라인에서 사용하는 도구로 인해 어려울 수 있지만, 다기능 및 실행 속도가 빠르고 매우 강력한 동영상 편집 도구로 사용할 수 있습니다.
이번에는 FFmpeg의 다음 기능을 사용했습니다.
사용한 동영상
NHK 크리에이티브 라이브러리 당구 동영상 을(를) 다운로드하여 가공했습니다. 비영리 목적이라면 편집하여 공개 가능한 동영상이 되고 있습니다.
장면 변화를 감지하여 썸네일 이미지 출력
커맨드 라인에서 다음 명령을 실행하면 동영상의 장면 변화를 감지하여 각 장면의 첫 번째 이미지를 축소판 이미지로 출력합니다. 장면 변화의 정도를 0~1.0까지로 설정할 수 있습니다만, 0.1로 변화가 작아도 검출할 수 있도록 설정했습니다. 또한 ffout이라는 파일명으로 처리 정보가 기재된 파일을 출력합니다.
$ ffmpeg -i billiards.mp4 -vf "select=gt(scene\,0.1), scale=640:360,showinfo" -vsync vfr output/%04d.jpg -f null - 2>ffout
출력한 파일 목록은 ↓입니다.
폴더의 축소판 이미지를 삭제하여 불필요한 장면 삭제
불필요한 장면이라고 생각하는 썸네일 이미지를 삭제합니다.
이번에는 당구 공의 확대 화상만 남기고 싶기 때문에, 그 이외의 화상을 삭제했습니다.
002.jpg 003.jpg 004.jpg
삭제 중입니다.
ffout 파일의 내용으로부터 장면 검출한 시간을 배열에 저장한다
Python 스크립트에서 ffout 파일에서 각 장면의 시작 시간을 추출합니다.
시작 시간은 pts_time:〇〇.〇〇의 형태로 기재되어 있습니다.
import re
from datetime import datetime
def loadData(file):
f = open(file)
data = f.read()
f.close()
return data
def getEndTime(data):
date_pattern = re.compile(r'time=(\d{2}:\d{2}:\d{2})')
match = re.findall(date_pattern, data)
dt = datetime.strptime(match[0], '%H:%M:%S')
endTime = dt.hour * 60 * 60 + dt.minute * 60 + dt.second
return endTime
def getTimes(data):
pattern = r'pts_time:([0-9]+\.[0-9]+)' # pts_timeの数値を抽出する
timeList = re.findall(pattern, data)
timeList = [float(n) for n in timeList] # str型をfloat型に変換
return timeList
if __name__ == '__main__':
data = loadData('ffout')
endTime = getEndTime(data)
timeList = getTimes(data)
timeList.append(endTime)
print(timeList)
결과
[1.7017, 5.9059, 13.8472, 17.0504, 19.8198, 21.6883, 23.7237, 25.7257, 34]
폴더의 이미지에 남아있는 축소판 이미지의 번호를 인덱스 배열에 저장
import os
def getFIleList(path):
fileList = os.listdir(path)
return fileList
def getTimeIndex(fileList):
pattern = r'([1-9]+[0-9]*).jpg'
index = []
for i, fl in enumerate(fileList):
temp = re.findall(pattern, fl)
if(temp != None):
index.append(temp[0])
index = [int(n) - 1 for n in index] # str型をfloat型に変換
return index
if __name__ == '__main__':
path = "./output"
fileList = getFIleList(path)
index = getTimeIndex(fileList)
print(index)
결과
[0, 4, 5, 6, 7]
폴더에 남은 썸네일 이미지에서 동영상 파일 생성 (동영상 잘라내기)
import subprocess
def writeFile(fileName, text):
f = open(fileName, 'w') # 書き込みモードで開く
f.write(text) # 引数の文字列をファイルに書き込む
f.close() # ファイルを閉じる
def generateCommand(index):
text = ''
for i, ii in enumerate(index):
delta = timeList[ii + 1] - timeList[ii]
cmd = 'ffmpeg -ss %s' % timeList[ii] + \
' -i billiards.mp4 -t %g' % delta + ' output/output%s.mp4' % i
print(cmd)
subprocess.call(cmd, shell=True)
text += 'file output/output' + str(i) + '.mp4\n'
return text
if __name__ == '__main__':
text = generateCommand(index)
writeFile('mylist.txt', text)
위의 스크립트를 실행하면 ffmpeg로 다음 명령을 실행하게 되어 5개의 mp4 파일이 생성됩니다.
ffmpeg -ss 1.7017 -i billiards.mp4 -t 4.2042 output/output0.mp4
ffmpeg -ss 19.8198 -i billiards.mp4 -t 1.8685 output/output1.mp4
ffmpeg -ss 21.6883 -i billiards.mp4 -t 2.0354 output/output2.mp4
ffmpeg -ss 23.7237 -i billiards.mp4 -t 2.002 output/output3.mp4
ffmpeg -ss 25.7257 -i billiards.mp4 -t 5.2743 output/output4.mp4
각 동영상 파일 연결
ffmpeg에서 파일을 나열하고 동영상을 연결하는 방법 를 참고했습니다.
↑의 파이썬 스크립트에서 mylist.txt
file output/output0.mp4
file output/output1.mp4
file output/output2.mp4
file output/output3.mp4
file output/output4.mp4
라고 기재되어 있습니다.
아래 명령을 실행하면 mylist 파일에 나열된 동영상 파일을 모두 연결하여 output.mp4 파일로 출력합니다.
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
이제 불필요한 장면이 삭제된 동영상이 완성됩니다.
Reference
이 문제에 관하여(FFmpeg로 동영상이 필요없는 장면 삭제 ~ 장면 검출 및 썸네일 이미지 출력 ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/otakoma/items/842b7417b1012fab9097
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
커맨드 라인에서 다음 명령을 실행하면 동영상의 장면 변화를 감지하여 각 장면의 첫 번째 이미지를 축소판 이미지로 출력합니다. 장면 변화의 정도를 0~1.0까지로 설정할 수 있습니다만, 0.1로 변화가 작아도 검출할 수 있도록 설정했습니다. 또한 ffout이라는 파일명으로 처리 정보가 기재된 파일을 출력합니다.
$ ffmpeg -i billiards.mp4 -vf "select=gt(scene\,0.1), scale=640:360,showinfo" -vsync vfr output/%04d.jpg -f null - 2>ffout
출력한 파일 목록은 ↓입니다.
폴더의 축소판 이미지를 삭제하여 불필요한 장면 삭제
불필요한 장면이라고 생각하는 썸네일 이미지를 삭제합니다.
이번에는 당구 공의 확대 화상만 남기고 싶기 때문에, 그 이외의 화상을 삭제했습니다.
002.jpg 003.jpg 004.jpg
삭제 중입니다.
ffout 파일의 내용으로부터 장면 검출한 시간을 배열에 저장한다
Python 스크립트에서 ffout 파일에서 각 장면의 시작 시간을 추출합니다.
시작 시간은 pts_time:〇〇.〇〇의 형태로 기재되어 있습니다.
import re
from datetime import datetime
def loadData(file):
f = open(file)
data = f.read()
f.close()
return data
def getEndTime(data):
date_pattern = re.compile(r'time=(\d{2}:\d{2}:\d{2})')
match = re.findall(date_pattern, data)
dt = datetime.strptime(match[0], '%H:%M:%S')
endTime = dt.hour * 60 * 60 + dt.minute * 60 + dt.second
return endTime
def getTimes(data):
pattern = r'pts_time:([0-9]+\.[0-9]+)' # pts_timeの数値を抽出する
timeList = re.findall(pattern, data)
timeList = [float(n) for n in timeList] # str型をfloat型に変換
return timeList
if __name__ == '__main__':
data = loadData('ffout')
endTime = getEndTime(data)
timeList = getTimes(data)
timeList.append(endTime)
print(timeList)
결과
[1.7017, 5.9059, 13.8472, 17.0504, 19.8198, 21.6883, 23.7237, 25.7257, 34]
폴더의 이미지에 남아있는 축소판 이미지의 번호를 인덱스 배열에 저장
import os
def getFIleList(path):
fileList = os.listdir(path)
return fileList
def getTimeIndex(fileList):
pattern = r'([1-9]+[0-9]*).jpg'
index = []
for i, fl in enumerate(fileList):
temp = re.findall(pattern, fl)
if(temp != None):
index.append(temp[0])
index = [int(n) - 1 for n in index] # str型をfloat型に変換
return index
if __name__ == '__main__':
path = "./output"
fileList = getFIleList(path)
index = getTimeIndex(fileList)
print(index)
결과
[0, 4, 5, 6, 7]
폴더에 남은 썸네일 이미지에서 동영상 파일 생성 (동영상 잘라내기)
import subprocess
def writeFile(fileName, text):
f = open(fileName, 'w') # 書き込みモードで開く
f.write(text) # 引数の文字列をファイルに書き込む
f.close() # ファイルを閉じる
def generateCommand(index):
text = ''
for i, ii in enumerate(index):
delta = timeList[ii + 1] - timeList[ii]
cmd = 'ffmpeg -ss %s' % timeList[ii] + \
' -i billiards.mp4 -t %g' % delta + ' output/output%s.mp4' % i
print(cmd)
subprocess.call(cmd, shell=True)
text += 'file output/output' + str(i) + '.mp4\n'
return text
if __name__ == '__main__':
text = generateCommand(index)
writeFile('mylist.txt', text)
위의 스크립트를 실행하면 ffmpeg로 다음 명령을 실행하게 되어 5개의 mp4 파일이 생성됩니다.
ffmpeg -ss 1.7017 -i billiards.mp4 -t 4.2042 output/output0.mp4
ffmpeg -ss 19.8198 -i billiards.mp4 -t 1.8685 output/output1.mp4
ffmpeg -ss 21.6883 -i billiards.mp4 -t 2.0354 output/output2.mp4
ffmpeg -ss 23.7237 -i billiards.mp4 -t 2.002 output/output3.mp4
ffmpeg -ss 25.7257 -i billiards.mp4 -t 5.2743 output/output4.mp4
각 동영상 파일 연결
ffmpeg에서 파일을 나열하고 동영상을 연결하는 방법 를 참고했습니다.
↑의 파이썬 스크립트에서 mylist.txt
file output/output0.mp4
file output/output1.mp4
file output/output2.mp4
file output/output3.mp4
file output/output4.mp4
라고 기재되어 있습니다.
아래 명령을 실행하면 mylist 파일에 나열된 동영상 파일을 모두 연결하여 output.mp4 파일로 출력합니다.
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
이제 불필요한 장면이 삭제된 동영상이 완성됩니다.
Reference
이 문제에 관하여(FFmpeg로 동영상이 필요없는 장면 삭제 ~ 장면 검출 및 썸네일 이미지 출력 ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/otakoma/items/842b7417b1012fab9097
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Python 스크립트에서 ffout 파일에서 각 장면의 시작 시간을 추출합니다.
시작 시간은 pts_time:〇〇.〇〇의 형태로 기재되어 있습니다.
import re
from datetime import datetime
def loadData(file):
f = open(file)
data = f.read()
f.close()
return data
def getEndTime(data):
date_pattern = re.compile(r'time=(\d{2}:\d{2}:\d{2})')
match = re.findall(date_pattern, data)
dt = datetime.strptime(match[0], '%H:%M:%S')
endTime = dt.hour * 60 * 60 + dt.minute * 60 + dt.second
return endTime
def getTimes(data):
pattern = r'pts_time:([0-9]+\.[0-9]+)' # pts_timeの数値を抽出する
timeList = re.findall(pattern, data)
timeList = [float(n) for n in timeList] # str型をfloat型に変換
return timeList
if __name__ == '__main__':
data = loadData('ffout')
endTime = getEndTime(data)
timeList = getTimes(data)
timeList.append(endTime)
print(timeList)
결과
[1.7017, 5.9059, 13.8472, 17.0504, 19.8198, 21.6883, 23.7237, 25.7257, 34]
폴더의 이미지에 남아있는 축소판 이미지의 번호를 인덱스 배열에 저장
import os
def getFIleList(path):
fileList = os.listdir(path)
return fileList
def getTimeIndex(fileList):
pattern = r'([1-9]+[0-9]*).jpg'
index = []
for i, fl in enumerate(fileList):
temp = re.findall(pattern, fl)
if(temp != None):
index.append(temp[0])
index = [int(n) - 1 for n in index] # str型をfloat型に変換
return index
if __name__ == '__main__':
path = "./output"
fileList = getFIleList(path)
index = getTimeIndex(fileList)
print(index)
결과
[0, 4, 5, 6, 7]
폴더에 남은 썸네일 이미지에서 동영상 파일 생성 (동영상 잘라내기)
import subprocess
def writeFile(fileName, text):
f = open(fileName, 'w') # 書き込みモードで開く
f.write(text) # 引数の文字列をファイルに書き込む
f.close() # ファイルを閉じる
def generateCommand(index):
text = ''
for i, ii in enumerate(index):
delta = timeList[ii + 1] - timeList[ii]
cmd = 'ffmpeg -ss %s' % timeList[ii] + \
' -i billiards.mp4 -t %g' % delta + ' output/output%s.mp4' % i
print(cmd)
subprocess.call(cmd, shell=True)
text += 'file output/output' + str(i) + '.mp4\n'
return text
if __name__ == '__main__':
text = generateCommand(index)
writeFile('mylist.txt', text)
위의 스크립트를 실행하면 ffmpeg로 다음 명령을 실행하게 되어 5개의 mp4 파일이 생성됩니다.
ffmpeg -ss 1.7017 -i billiards.mp4 -t 4.2042 output/output0.mp4
ffmpeg -ss 19.8198 -i billiards.mp4 -t 1.8685 output/output1.mp4
ffmpeg -ss 21.6883 -i billiards.mp4 -t 2.0354 output/output2.mp4
ffmpeg -ss 23.7237 -i billiards.mp4 -t 2.002 output/output3.mp4
ffmpeg -ss 25.7257 -i billiards.mp4 -t 5.2743 output/output4.mp4
각 동영상 파일 연결
ffmpeg에서 파일을 나열하고 동영상을 연결하는 방법 를 참고했습니다.
↑의 파이썬 스크립트에서 mylist.txt
file output/output0.mp4
file output/output1.mp4
file output/output2.mp4
file output/output3.mp4
file output/output4.mp4
라고 기재되어 있습니다.
아래 명령을 실행하면 mylist 파일에 나열된 동영상 파일을 모두 연결하여 output.mp4 파일로 출력합니다.
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
이제 불필요한 장면이 삭제된 동영상이 완성됩니다.
Reference
이 문제에 관하여(FFmpeg로 동영상이 필요없는 장면 삭제 ~ 장면 검출 및 썸네일 이미지 출력 ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/otakoma/items/842b7417b1012fab9097
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import os
def getFIleList(path):
fileList = os.listdir(path)
return fileList
def getTimeIndex(fileList):
pattern = r'([1-9]+[0-9]*).jpg'
index = []
for i, fl in enumerate(fileList):
temp = re.findall(pattern, fl)
if(temp != None):
index.append(temp[0])
index = [int(n) - 1 for n in index] # str型をfloat型に変換
return index
if __name__ == '__main__':
path = "./output"
fileList = getFIleList(path)
index = getTimeIndex(fileList)
print(index)
[0, 4, 5, 6, 7]
import subprocess
def writeFile(fileName, text):
f = open(fileName, 'w') # 書き込みモードで開く
f.write(text) # 引数の文字列をファイルに書き込む
f.close() # ファイルを閉じる
def generateCommand(index):
text = ''
for i, ii in enumerate(index):
delta = timeList[ii + 1] - timeList[ii]
cmd = 'ffmpeg -ss %s' % timeList[ii] + \
' -i billiards.mp4 -t %g' % delta + ' output/output%s.mp4' % i
print(cmd)
subprocess.call(cmd, shell=True)
text += 'file output/output' + str(i) + '.mp4\n'
return text
if __name__ == '__main__':
text = generateCommand(index)
writeFile('mylist.txt', text)
위의 스크립트를 실행하면 ffmpeg로 다음 명령을 실행하게 되어 5개의 mp4 파일이 생성됩니다.
ffmpeg -ss 1.7017 -i billiards.mp4 -t 4.2042 output/output0.mp4
ffmpeg -ss 19.8198 -i billiards.mp4 -t 1.8685 output/output1.mp4
ffmpeg -ss 21.6883 -i billiards.mp4 -t 2.0354 output/output2.mp4
ffmpeg -ss 23.7237 -i billiards.mp4 -t 2.002 output/output3.mp4
ffmpeg -ss 25.7257 -i billiards.mp4 -t 5.2743 output/output4.mp4
각 동영상 파일 연결
ffmpeg에서 파일을 나열하고 동영상을 연결하는 방법 를 참고했습니다.
↑의 파이썬 스크립트에서 mylist.txt
file output/output0.mp4
file output/output1.mp4
file output/output2.mp4
file output/output3.mp4
file output/output4.mp4
라고 기재되어 있습니다.
아래 명령을 실행하면 mylist 파일에 나열된 동영상 파일을 모두 연결하여 output.mp4 파일로 출력합니다.
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
이제 불필요한 장면이 삭제된 동영상이 완성됩니다.
Reference
이 문제에 관하여(FFmpeg로 동영상이 필요없는 장면 삭제 ~ 장면 검출 및 썸네일 이미지 출력 ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/otakoma/items/842b7417b1012fab9097
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
file output/output0.mp4
file output/output1.mp4
file output/output2.mp4
file output/output3.mp4
file output/output4.mp4
$ ffmpeg -f concat -i mylist.txt -c copy output.mp4
Reference
이 문제에 관하여(FFmpeg로 동영상이 필요없는 장면 삭제 ~ 장면 검출 및 썸네일 이미지 출력 ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/otakoma/items/842b7417b1012fab9097텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)