doc:appunti:linux:video:fix_smartphone_portrait_videos
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
doc:appunti:linux:video:fix_smartphone_portrait_videos [2018/04/07 12:29] – [The Compromise Solution] niccolo | doc:appunti:linux:video:fix_smartphone_portrait_videos [2018/04/07 15:47] (current) – [The Gradient Overlay Mask] niccolo | ||
---|---|---|---|
Line 12: | Line 12: | ||
A compromise solution is to **cut out a central area of the video** and **add to the sides some artifact** that simulates the presence of a portion of video that does not actually exist. I find that solution by far more acceptable than the original video: | A compromise solution is to **cut out a central area of the video** and **add to the sides some artifact** that simulates the presence of a portion of video that does not actually exist. I find that solution by far more acceptable than the original video: | ||
- | {{final_video_interpolated.jpg? | + | {{final_video_interpolated.jpg? |
So we have to: | So we have to: | ||
Line 22: | Line 22: | ||
{{choose_crop_area.png? | {{choose_crop_area.png? | ||
- | We wrote a **Python script** to assist in step #1, which calculate all the required numbers just provinding two parameters: the **crop_aspect** and the **offset_y**. | + | We wrote a **[[# |
Adjust the **crop_aspect** from 0.0 (which selects a square) to 1.0 (which selects the full rectangle of the picture). Using a square-shaped crop area we will get the **highest zoom** level into the video, but we will cut-out | Adjust the **crop_aspect** from 0.0 (which selects a square) to 1.0 (which selects the full rectangle of the picture). Using a square-shaped crop area we will get the **highest zoom** level into the video, but we will cut-out | ||
We can move the cropped region to the top of the image by setting **offset_y** to 0.0. Move it to te bottom by setting it to 1.0. To crop the image at the **center** of the screen, use an // | We can move the cropped region to the top of the image by setting **offset_y** to 0.0. Move it to te bottom by setting it to 1.0. To crop the image at the **center** of the screen, use an // | ||
- | ===== The Overlay Mask ===== | + | ===== Cropped Region and Fake Background |
+ | Once selected the cropped region, a **fake background** is created by simply **stretching** the region to **16:9 aspect ratio** and applying a **blur effect**. | ||
+ | |||
+ | {{cropped_region.jpg? | ||
+ | {{fake_background.jpg? | ||
+ | |||
+ | ===== The Gradient Overlay Mask ===== | ||
+ | |||
+ | When the cropped image is placed above the background, it is quite annoying to see the **sharp edge** of the image. A better approach is to gradually fade the image at the right and at left edges. This requires to blend the image and the background using a **gradient mask**. We prepared the mask as a **{{gradient_overlay_mask.png? | ||
+ | |||
+ | < | ||
+ | convert -size 768x768 \ | ||
+ | -define " | ||
+ | gradient: | ||
+ | -define " | ||
+ | gradient: | ||
+ | -composite -channel a -negate -rotate 90 tmp_mask.png | ||
+ | </ | ||
+ | |||
+ | **NOTICE**: It seems that [[https:// | ||
===== The ffmpeg Recipe ===== | ===== The ffmpeg Recipe ===== | ||
+ | The first step is to **remove the rotation metatag** from the input video. It seems that ffmpeg is unable to remove the metatag and apply the required video filters in the same pass, so we need to make a temporary copy of the input video file, without re-encoding it: | ||
+ | |||
+ | < | ||
+ | ffmpeg -i input_video.mp4 -c copy -metadata: | ||
+ | </ | ||
+ | |||
+ | finally we invoke **ffmpeg** to do all the magic. We use a **filter_complex** incantation: | ||
+ | |||
+ | < | ||
+ | ffmpeg -i tmp_norotate.mp4 -loop 1 -i tmp_mask.png -filter_complex "\ | ||
+ | [0:v]split [a][b]; \ | ||
+ | [a]transpose=1, | ||
+ | [b]transpose=1, | ||
+ | [1: | ||
+ | [crop][mask]alphamerge [masked]; \ | ||
+ | [back][masked]overlay=299: | ||
+ | " video_out.mp4 | ||
+ | </ | ||
+ | |||
+ | The first video stream **%%[0: | ||
+ | |||
+ | ===== The Python Script ===== | ||
+ | |||
+ | The Python script **{{smartphonevideo_2landscape.txt|smartphonevideo_2landscape}}** will make the calculation to prepare the whole incantation: | ||
+ | |||
+ | < | ||
+ | smartphonevideo_2landscape video_file [crop_aspect] [offset_y] > ffmpeg_recipe | ||
+ | source ffmpeg_recipe | ||
+ | </ | ||
+ | |||
+ | You have to edit the script to adjust the size of the input video (default 1280x720), the rotation needed (default 1 = 90 deg clockwise), and the size of output video produced (default 1366x768). |
doc/appunti/linux/video/fix_smartphone_portrait_videos.txt · Last modified: 2018/04/07 15:47 by niccolo