User Tools

Site Tools


doc:appunti:linux:video:ffmpeg_stack_horizontally

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
doc:appunti:linux:video:ffmpeg_stack_horizontally [2021/10/28 11:19] niccolodoc:appunti:linux:video:ffmpeg_stack_horizontally [2021/10/28 11:43] (current) niccolo
Line 2: Line 2:
  
 I created a Unix shell script to do a **side-by-side comparison** between videos recorded with my two action cameras: a new **SJCAM 8 Pro** and the old **Xiaomi Yi**. I created a Unix shell script to do a **side-by-side comparison** between videos recorded with my two action cameras: a new **SJCAM 8 Pro** and the old **Xiaomi Yi**.
 +
 +Suppose that we have two videos taken simultaneously with the two cameras:
  
 {{.:ffmpeg:video1.jpg?320|}} {{.:ffmpeg:video1.jpg?320|}}
 {{.:ffmpeg:video2.jpg?320|}} {{.:ffmpeg:video2.jpg?320|}}
  
-The result is a video like the following: the **central part** of each video is stacked horizontally on the final video, two **labels are overlayed** on the bottom corners, the **audio** from the first video is mixed into the **left channel** of the resulting video and the audio from the second video goes to the **right channel**.+The result will be a video like the following: the **central part** of each video is stacked horizontally on the final frame, two **labels are overlayed** on the bottom corners, the **audio** from the first video is mixed into the **left channel** of the resulting video and the audio from the second video goes to the **right channel**.
  
 {{.:ffmpeg:video_hstack.jpg?640|}} {{.:ffmpeg:video_hstack.jpg?640|}}
Line 13: Line 15:
  
 The script can take into account that the videos may be **out of sync**: it is possible to pass **two timestamps** referring at the same instant captured into both videos. The script will **shift the videos presentation time** each-other, so that both will be synced.  The script can take into account that the videos may be **out of sync**: it is possible to pass **two timestamps** referring at the same instant captured into both videos. The script will **shift the videos presentation time** each-other, so that both will be synced. 
 +
 +The script has some constraints. It requires the **Bash shell**, because it uses the **%%((expression))%%** to do arithmetic evaluation. The script requires also the **Python** interpreter, just to do a floating point difference and properly formats the result.
 +
 +<code>
 +#!/bin/bash
 +
 +# Take the central part of two videos and stack them horizontally.
 +# Audio from the first video is merged into the left channel of the
 +# resulting video, audio from the second video goes to the right.
 +# Two lables are overlayed on the bottom left and right corners.
 +
 +# https://stackoverflow.com/questions/35349935/ffmpeg-crop-with-side-by-side-merge
 +# https://unix.stackexchange.com/questions/233832/merge-two-video-clips-into-one-placing-them-next-to-each-other
 +# https://trac.ffmpeg.org/wiki/AudioChannelManipulation
 +
 +# Left and right videos.
 +#VIDEO_1='20211023135104_0322.MP4'
 +#VIDEO_2='YDXJ0851.mp4'
 +VIDEO_1="$1"
 +VIDEO_2="$2"
 +
 +# Two timestamps which should be synced.
 +#TIME_1='15.482'
 +#TIME_2='16.282'
 +TIME_1="$3"
 +TIME_2="$4"
 +
 +# Labels to be superimposed on the two halves.
 +#LABEL_1='SJ8Pro'
 +#LABEL_2='Xiaomi Yi'
 +LABEL_1="$5"
 +LABEL_2="$6"
 +
 +#OUTPUT='output.mkv'
 +OUTPUT="$7"
 +
 +if [ -z "$VIDEO_1" -o -z "$VIDEO_2" -o \
 +     -z "$TIME_1"  -o -z "$TIME_2"  -o \
 +     -z "$LABEL_1" -o -z "$LABEL_2" -o \
 +     -z "$OUTPUT" ]; then
 +    echo
 +    echo "Usage: $(basename $0) [video1] [video2] [time1] [time2] [label1] [label2] [output]"
 +    echo
 +    echo "  Example: $(basename $0) 20211023135104_0322.MP4 YDXJ0851.mp4 15.482 16.282 SJ8Pro 'Xiaomi Yi' output.mkv"
 +    echo
 +    exit 1
 +fi
 +
 +# Do the math, etc...
 +if (( $(echo "$TIME_1 > $TIME_2" | bc -l) )) ; then
 +    TO_1="$(python -c "print('%0.3f' % ($TIME_1 - $TIME_2,))")"
 +    TO_2='0.000'
 +else
 +    TO_1='0.000'
 +    TO_2="$(python -c "print('%0.3f' % ($TIME_2 - $TIME_1,))")"
 +fi
 +
 +# Font and style for labels.
 +FONT='fontfile=/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf:'
 +STYLE='fontcolor=yellow:fontsize=48:box=1:boxcolor=black@0.5:boxborderw=10'
 +# Labels placement.
 +L1X='20'
 +L2X='(w-text_w-20)'
 +L1Y='(h-text_h-20)'
 +L2Y='(h-text_h-20)'
 +
 +ffmpeg -ss "$TO_1" -i "$VIDEO_1" -ss "$TO_2" -i "$VIDEO_2" \
 +    -filter_complex \
 +     "[0:v]crop=iw/2:ih:ow/2:0[left]; \
 +      [1:v]crop=iw/2:ih:ow/2:0[right]; \
 +      [left][right]hstack=shortest=1[vs]; \
 +      [0:a][1:a]amerge=inputs=2,pan=stereo|c0<c0+c1|c1<c2+c3[a]; \
 +      [vs]drawtext=${FONT}text='${LABEL_1}':${STYLE}:x=${L1X}:y=${L1Y},drawtext=${FONT}text='${LABEL_2}':${STYLE}:x=${L2X}:y=${L2Y} [v]" \
 +    -map '[v]' -map '[a]' \
 +    "$OUTPUT"
 +</code>
doc/appunti/linux/video/ffmpeg_stack_horizontally.1635412797.txt.gz · Last modified: 2021/10/28 11:19 by niccolo