wiki/docs/media/index.md

6.2 KiB

Media (General)

Audio

Split file with cue sheet and use filename from cue sheet

:::shell
shnsplit -D -f file.cue -t "%n %t" -o "flac flac -8 -o %f -" file.flac

To directly encode to opuus:

:::shell
shnsplit -D -f file.cue -t "%n %t" -o "cust ext=opus opusenc --bitrate=160k - %f" file.flac

Remove all tags except MusicBrainz tags from flac files

:::shell
for i in *.flac; do tags=$(metaflac --export-tags-to=- $i | grep -E '^MUSICBRAINZ_'); metaflac --remove-all-tags $i; metaflac --import-tags-from=- $i <<< $tags; done

Downmix 5.1/7.1 to 2.0

:::shell
mpv --oac=flac --audio-channels=stereo --oacopts=compression_level=0 --o=outfile.flac infile.flac

Record pulseaudio device to flac

:::shell
parec [ -d DEVICE ] | flac --endian=little --channels=2 --bps=16 --sample-rate=48000 --sign=signed -o foo.flac -

Copy Matroska Chapters to Opus

Requires the metadata to fit in one ogg page (so no cover art :().

:::shell
mkvextract file.mka chapters | xq -r 'def pad: tostring | (3 - length) as $l | ("0" * $l)[:$l] + .; [[.Chapters.EditionEntry.ChapterAtom[] | {start: .ChapterTimeStart, name: .ChapterDisplay.ChapterString}] | to_entries[] | "CHAPTER\(.key|pad)=\(.value.start)\nCHAPTER\(.key|pad)NAME=\(.value.name)"] | join("\n")' | opustags -i -S file.opus

Video

Copy DVD stream to file [with dvd already copied to local directory]

:::shell
mpv --stream-dump=1.mkv dvd://1 [--dvd-device path/to/dvd]

Images

Apply EXIF rotation to JPEG images

Requires jhead and jpegtran.

:::shell
nix shell nixpkgs#jhead nixpkgs#libjpeg.bin
jhead -ft -autorot *.JPG

MKV

Fix mimetype of font attachments

Some matroska files have the mimetype for font attachment for fonts set to application/octet-strem.

:::shell
 mkvpropedit --attachment-mime-type font/sfnt --update-attachment mime-type:application/octet-stream file.mkv

FFmpeg

Create color timeline image from video

:::shell
(infile=in.mkv; outfile=out.png; rows=320; width=1920; height=1080; ffmpeg -i $infile -vf tblend=all_mode=average,fps=${rows}/$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $infile),scale=1:1,scale=${width}/${rows}:${height},setsar=1,tile=${rows}x1 -frames:v 1 $outfile)

Show duration of file in seconds

:::shell
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 file.mkv

Remove EIA-608 subtitles from video bitstream

(source)

:::shell
ffmpeg -i infile.mkv -c copy -bsf:v "filter_units=remove_types=6" outfile.mkv

QP file

replace 24/1.001 with framerate

:::shell
ffprobe -i infile.mkv -print_format json -show_chapters -loglevel error | jq -r '.chapters[].start / 1000000000 * 24/1.001 | round | tostring + " I"' >> foo.qp

Manga

Convert greyscale images to actuual greyscale

For some reasons, many releases encode greyscale manga pages as yuv420. Sadly, the chroma layers are not completely empty but include some (almost invisible) noise. This fixes that for lower battery comsumption, a really small file size gain and just because it seems right.

This only works for pages with the same size (image2/ffmpeg limitation), but releases suffering from this mostly fulfill this requirement.

WARNING: This uses some heuristics (SSIM > 98) to determine if a page is greyscale. This may not work all the time (it did for me though). Please verify if all converted images actually are greyscale.

:::shell
ffmpeg -loglevel error -f lavfi -i "movie=%03d.jpg:f=image2,split=2[orig][in2];[in2]extractplanes=y[grey];[orig][grey]ssim=-" -f null - >> ssim
while read frame;do (( $(cut -d' ' -f5 <<< $frame | cut -c 7-8) < 98 )) || {file=$(printf "%03d.jpg\n" $(cut -d' ' -f1 <<< $frame|cut -d: -f2)); echo $file; jpegtran -copy none -optimize -grayscale -outfile $file $file}; done < ssim
jpegoptim -s *.jpg
exiftool -overwrite_original -all= *.jpg

# print all converted images for verification
grep -E 'All:0.(9[0-8]|[0-8][0-9])' ssim

Merge page spreads to single page

Use function merge_pages right-page left-page (without .jpg). Result will be written to left-page-right-page.jpg`.

:::shell
function merge_pages() {
    convert ${2}.jpg ${1}.jpg +append ${1}-${2}.jpg
    exiftool -overwrite_original -all= ${1}-${2}.jpg
}

# remove single pages
mkdir single_pages
for i in ???-???.jpg;do mv $(cut -d- -f1 <<< $i).jpg $(cut -d- -f2 <<< $i) single_pages;done

mpv

:::shell
mpv --pause --demuxer=rawvideo --demuxer-rawvideo-mp-format=bgra --demuxer-rawvideo-w=288 --demuxer-rawvideo-h=162 FILE

Convert to tiles

:::shell
ffmpeg -codec:v rawvideo -pixel_format bgra -video_size 288:162 -f image2 -pattern_type glob -i '*' -vf tile=layout=10x10 tile-%04d.png

Download

Bilibili live recording

:::shell
curl 'https://api.live.bilibili.com/xlive/web-room/v1/record/getLiveRecordUrl?rid=R1sx411c7Xn&platform=html5'|jq -r '.data.list | map(.url) | to_entries[] | .value + "\n  out=" + (.key|tostring) + ".flv"' | aria2c --auto-file-renaming=false -x 16 -j 10 -i -
mkvmerge '[' $(find . -name '*.flv'|sort -V) ']' -o merge.mkv

PDF

Downsample bitmap PDF

Useful for sending large 300/600 dpi scans as e-mail. Change pdfimage32 to pdfimage8 for greyscale, 300 to the input DPI and DownScaleFactor to the desired downscaling. For some reason fails when setting compression to JPEG.

:::shell
gs -sDEVICE=pdfimage24 -r300 -dDownScaleFactor=2 -o downscaled.pdf document.pdf

Imagemagick supports JPEG. Set your desired output density and JPEG quality.

:::shell
convert -density 300 -compress jpeg -quality 80 document.pdf downscaled.pdf

Screen sharing

Since there is no good support for WebRTC screensharing with wayland, a virtual webcam device can be used.

:::shell
sudo modprobe v4l2loopback exclusive_caps=1 card_label=screensharing # only has to be done once
wf-recorder --muxer=v4l2 --codec=rawvideo --file=/dev/video2 -x yuv420p # adjust /dev/video2 to the actual device

To remove the virtual webcam device run sudo modprobe -r v4l2loopback