트윗 캡쳐 후 비디오 만들기 8 - Result video
안녕하세요. 카이랏입니다.
최종적으로 결과물을 공유하고자 합니다.
그 전에 몇 가지 코드의 수정 사항을 공유합니다.
1. 터미널 명령 개선
ffmpeg -framerate 1 -i %d.png -vf "scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuva420p -metadata:s:v:0 alpha_mode="1" -auto-alt-ref 0 -codec:v libvpx output.webm
과거에는 첫 번째 사진을 기준으로 다른 모든 사진들의 크기가 조정되고 영상도 첫 번째 사진을 기준으로 만들어졌습니다.
하지만 변경된 명령어에서는 1920 x 1080 사이즈로 영상의 크기가 고정됩니다.
또한 이 크기를 기준으로 이미지들이 상하좌우로 늘어나지 않고 중앙으로 배치되도록 수정하였습니다.
1). scale 필터는 입력 비디오의 크기를 변경합니다. 여기서는 비디오를 1920x1080 크기로 축소시킵니다.
2). force_original_aspect_ratio=decrease 옵션을 사용하여 원래 이미지의 종횡비를 유지하면서 이미지를 축소합니다.
이것은 원래 이미지가 1920x1080보다 작은 경우 이미지의 크기가 더 이상 줄어들지 않도록 하는 데 도움이 됩니다.
3). pad 필터는 이미지 크기가 축소되었거나 이미지의 종횡비가 16:9와 같지 않은 경우에만 적용됩니다.
이 필터는 입력 이미지의 가장자리에 검은 색 여백을 추가하여 이미지를 1920x1080 크기로 패딩합니다.
4). (ow-iw)/2:(oh-ih)/2 옵션은 패딩이 이미지를 화면 중앙에 배치하도록 설정합니다.
2. 사진 및 영상의 둥근 모서리 처리
현재 tweet-capture로 저장되는 이미지 파일 형식은 png 파일이며 둥근 모서리가 있는 이미지였습니다.
그러나 이것을 jpg로 변경하면 둥근 모서리가 사라지는 현상을 봤습니다. 따라서 왜 그런지 알아봤습니다.
1). 알파값
알파값은 RGB 외에 RGBA로 표시합니다. 마지막의 A 값이 Alpha 값입니다.
특별히 alpha 값은 투명도를 제어하는데 사용되는 값입니다.
따라서 이 값을 통해 사진이나 영상의 둥근 모서리를 표현할 수 있습니다.
2). jpg 와 png
jpg에는 기본적으로 alpha 값을 담지 않습니다.
따라서 둥근 모서리를 표현하기 위해서는 다른 색으로 그 영역을 칠해야 합니다.
만약 배경색이 검은색이라면 검은색으로 둥근 모서리를 만들면 투명한 것처럼 보여집니다.
그러나 만약 배경의 이미지가 들어간다면 표현이 어려울 것입니다.
아직 이 부분은 어떻게 처리해야 하는지 방법을 찾지 못했습니다.
그러나 png 파일에는 alpha 값이 저장됩니다. 따라서 배경이 어떤 것이 와도 투명하게 둥근 모서리를 보여줄 수 있습니다.
따라서 기본적으로 저장된 png 파일을 사용하도록 하였습니다.
3). mp4 와 webm
jpg와 마찬가지로 mp4에는 alpha 값이 저장되지 않습니다.
그러나 webm 형식에는 alpha 값이 저장됩니다.
따라서 둥근 모서리를 표현하고 싶다면 webm으로 저장하면 됩니다.
webm 은 VLC 플레이어로 보면 둥근 모서리가 나오지 않습니다.
그러나 Chrome에서 플레이하면 둥근 모서리가 잘 나옵니다.
아마도 webm 파일 표준을 google 에서 만들었기 때문으로 추측됩니다.
결론적으로 둥근 모서리를 표현하기 위해서는(투명도를 포함하기 위해서) png 와 webm 포멧을 사용하여 영상을 만들어야 합니다.
3. 코드 변경
위의 명령어에 따라 코드도 변경됩니다.
async def make_video_from_images(self,
show_second=1,
image_path="images",
output_filename="output") :
try:
print(f"Start make_video_from_images")
workdir = os.path.dirname(os.path.realpath(__file__))
#### output path
if os.path.exists(workdir + "/output") == False:
os.mkdir(workdir + "/output")
output_path = workdir + "/output" + f"/{output_filename}" + ".webm"
image_path = workdir + f"/{image_path}" + "/%d.png"
################################################################
# 중요! 기본적인 명령어는 아래와 같다.
# 더불어 파일명을 명명할 때 무조건 xxx%03d.jpg 와 같은 형식으로 사용하는 것이 좋다. 이유는 이것을 보고 파일의 순서를 정하기 때문이다.
################################################################
if show_second <= 0:
raise Exception("show second must be bigger than zero")
################################################################
# 아래의 코드의 터미널 명령어
# ffmpeg -framerate 1 -i %d.png -vf "scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuva420p -metadata:s:v:0 alpha_mode="1" -auto-alt-ref 0 -codec:v libvpx output.webm
################################################################
ffmpeg = (FFmpeg().option("y")
.input(image_path, r="{0}".format(1/show_second))
.output(output_path, {"pix_fmt": "yuva420p",
"metadata:s:v:0": "alpha_mode=1",
"auto-alt-ref": "0",
"codec:v": "libvpx",},
filter_complex="[0:v]scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2", crf=24,))
'''
################################################################
# 아래 코드의 터미널 명령어
# ffmpeg -framerate 1 -i %d.png -vf "scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuv420p -codec:v mpeg4 output.mp4
# 아래의 내용은 mpeg4 코덱을 사용하여 출력하는 내용이다. 그러나 모서리가 알파값으로 처리된 png 파일은
# mpeg4 코덱에서 알파값을 지원하지 않기 때문에 둥근 모서리가 사라진다.
################################################################
ffmpeg = (FFmpeg().option("y")
.input(image_path, r="{0}".format(1/show_second))
.output(output_path, vcode="mpeg4",
filter_complex="[0:v]scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2", crf=24,))
'''
################################################################
# 여기서 비동기 처리를 한다.
await ffmpeg.execute()
################################################################
print(f"End make_video_from_images")
except Exception as e:
print(f'Error={e}', self.make_video_from_images.__name__)
return
4. 최종 결과
키워드는 "Apple", "Samsung", "Orange", "Nature" 순서입니다.
검색 우선순위는 popular 이고 rt(retweet)이 많이 된 순서로 정렬하였습니다.
이전영상입니다. 약간 이상하죠? ^^;;
* 추가적으로 이 코드에 UI를 추가하여 사용자가 쓰기 편리하도록 기능을 구현할 예정입니다.
Hello. This is Kairat.
I would like to finally share the result.
Share some code fixes before that.
1. Improved terminal commands
ffmpeg -framerate 1 -i %d.png -vf "scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad =1920:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuva420p -metadata:s:v:0 alpha_mode="1" -auto-alt-ref 0 -codec:v libvpx output .webm
In the past, all other photos were resized based on the first photo and the video was also created based on the first photo.
However, the size of the video is fixed at 1920 x 1080 in the changed command.
Also, based on this size, the images are placed in the center without stretching up, down, left, or right. Modified .
1). The scale filter changes the size of the input video. Here we scale down the video to 1920x1080.
2). Use the force_original_aspect_ratio=decrease option to scale down the image while maintaining the aspect ratio of the original image.
This helps ensure that the image is no longer scaled down if the original image is smaller than 1920x1080.
3). The pad filter is applied only when the image is scaled down or when the image aspect ratio is not equal to 16:9.
This filter pads the image to a size of 1920x1080 by adding black padding to the edges of the input image.
4). The (ow-iw)/2:(oh-ih)/2 option sets the padding to center the image on the screen.
2. Handling rounded corners for photos and videos
The image file format currently saved as tweet-capture is a png file and has rounded corners.
However, when I changed this to jpg, I saw that the rounded corners disappeared. So I figured out why.
1). Alpha value
Alpha value is displayed as RGBA in addition to RGB. The last A value is the Alpha value.
Specially, the alpha value is used to control transparency.
Thus, you can express the rounded corners of the photo or video through this value.
2). jpg and png
jpg does not contain alpha by default.
So, to represent the rounded corners, you need to paint the area with a different color.
If the background color is black, round the corners with black to make it appear transparent.
However, if a background image is included, it will be difficult to express.
I haven't figured out how to handle this yet.
but alpha value is saved in png file. So you can show transparent rounded corners no matter what the background is.
Therefore, the saved png file is used by default.
3). mp4 and webm
Like jpg, mp4 does not store alpha values.
However, the alpha value is stored in the webm format.
So if you want to express rounded corners, you can save it as webm.
Webm does not have rounded corners when viewed with VLC Player.
However, when I play in Chrome, the rounded corners work fine.
It is probably because the webm file standard was created by google.
In conclusion, in order to express rounded corners (to include transparency), images must be created using png and webm formats.
3. Code changes
The above command also changes the code.
async def make_video_from_images(self,
show_second=1,
image_path="images",
output_filename="output") :
try:
print(f"Start make_video_from_images")
workdir = os.path.dirname(os.path.realpath(__file__))
#### output path
if os.path.exists(workdir + "/output") == False:
os.mkdir(workdir + "/output")
output_path = workdir + "/output" + f"/{output_filename}" + ".webm"
image_path = workdir + f"/{image_path}" + "/%d.png"
############################################### ##############
# important! The basic command is as follows.
# In addition, when naming a file, it is recommended to use it in a format such as xxx%03d.jpg. The reason is that it looks at this and determines the order of the files.
############################################### ##############
if show_second <= 0:
raise Exception("show second must be bigger than zero")
############################################### ##############
# terminal commands in the code below
# ffmpeg -framerate 1 -i %d.png -vf "scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuva420p -metadata:s:v:0 alpha_mode="1" -auto-alt-ref 0 -codec:v libvpx output.webm
############################################### ##############
ffmpeg = (FFmpeg().option("y")
.input(image_path, r="{0}".format(1/show_second))
.output(output_path, {"pix_fmt": "yuva420p",
"metadata:s:v:0": "alpha_mode=1",
"auto-alt-ref": "0",
"codec:v": "libvpx",},
filter_complex="[0:v]scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2", crf=24,) )
'''
############################################### ##############
# terminal commands in the code below
# ffmpeg -framerate 1 -i %d.png -vf "scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -pix_fmt yuv420p -codec:v mpeg4 output.mp4
# The following contents are output using the mpeg4 codec. However, png files with corners treated as alpha values
# The rounded corners disappear because the mpeg4 codec does not support alpha values.
############################################### ##############
ffmpeg = (FFmpeg().option("y")
.input(image_path, r="{0}".format(1/show_second))
.output(output_path, vcode="mpeg4",
filter_complex="[0:v]scale=w=1920:h=1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2", crf=24,) )
'''
############################################### ##############
# Do asynchronous processing here.
await ffmpeg.execute()
############################################### ##############
print(f"End marke_video_from_images")
except Exception as e:
print(f'Error={e}', self.make_video_from_images.__name__)
return
4. Final result
Keywords are "Apple", "Samsung", "Orange", "Nature" in order.
The search priority is popular and sorted in order of the most rt (retweet).
This is the previous video. a bit weird right? ^^;
* Additional UI will be added to this code to make it easier for users to use.