作为一名成年男性,硬盘里存着大量视频文件也是很合理的,但是一个文件动辄几个G还是有点伤,为了节省点可怜的空间,实验了一番后发现把h264转成h265通常能减少30%~40%的空间占用,有时候甚至能减少60%,同时对画质也几乎没有影响(反正我是没看出来),于是决定有选择性地把一些视频转成h265的。

简单粗暴版

一开始是直接用命令:

ffmpeg -hwaccel cuda -i input.mp4 -c:v hevc_nvenc -c:a libopus -crf 26 output.mp4

但是这样比较麻烦,从历史记录里面调出来之后还要移动光标到input处手动改文件名,output处也要改,转码完之后还要把原文件删除,再把新文件重命名为原文件名,着实麻烦。

于是写了一个函数放到.zshrc里面:

vcompress(){
    ls -lh $1 # 原始大小
    eval "ffpb -hwaccel cuda -i "$1" -c:v hevc_nvenc -c:a libopus -crf 26 1"$1   
    trash $1 # 把文件放到回收站里
    mv 1$1 $1
    ls -lh $1 # 转码后的大小
}

这样只要在Dolphin(KDE的文件管理器)里面呼出终端,然后vcompress xxx.mp4就可以了。

但是这个函数有几个问题,一是有时候转码后的文件反而会比原文件更大,如果能加个确认就更好了,二是中途出错了也不会停下来,就直接把原文件扔回收站里了,于是又升级了一下:

#!/bin/bash

# 确保有参数
if [[ $# -eq 0 ]] ; then
    echo "No specified file."
    exit 1
fi

# 出错直接退出
set -e

ls -lh $1

eval "ffpb -hwaccel cuda -i "$1" -c:v hevc_nvenc -c:a libopus -crf 26 "$1".opt.mp4"

ls -lh $1".opt.mp4"

# 确认
read -p "Are you sure? " -n 1 -r
echo 
if [[ $REPLY =~ ^[Yy]$ ]]
then
    trash $1
    mv $1".opt.mp4" $1
fi

bash脚本真难写)

把脚本放到~/.local/bin里面就完事了,这个版本确实比之前的强多了。

至尊奢华版

但是人的欲望是没有尽头的,现在又觉得每次按F4调出终端再输入有点烦,想着能不能右键文件,就可以直接在菜单里进行操作,万幸我用的是KDE,根据文档,这个东西叫作Service Menu,写个配置文件就行了,如果是Windows的话估计又要在反人类的注册表编辑器里面搞来搞去了。

vcompress.desktop:

[Desktop Entry]
Type=Service
; 仅用于mp4文件
MimeType=video/mp4;
Actions=videoCompress 
; 显示在菜单顶层
X-KDE-Priority=TopLevel

[Desktop Action videoCompress]
Name=Transcode video to HEVC
Name[zh_CN]=将视频转码至HEVC
Icon=browser-download
Exec=/bin/bash ~/.local/bin/vcompress_gui %f

把这个文件放到/usr/share/kio/servicemenus里面,重新打开Dolphin,右键一个视频文件:

右键菜单

然后脚本也要跟着改,毕竟不能直接输入输出了,还好贴心的KDE提供了kdialog,可以显示对话框:

#!/bin/bash

# exit on error
set -e

kdialog --passivepopup "Converting "$1 1

# original size
size_o=`du -h $1 | cut -f1`
# transcode with ffmpeg
eval "ffmpeg -hwaccel cuda -i "$1" -c:v hevc_nvenc -c:a libopus -crf 26 "$1".opt.mp4"
# size after transcoding
size_a=`du -h $1.opt.mp4 | cut -f1`

kdialog --yesno $size_o" => "$size_a"\nAre you sure?"
if [[ $? -ne 0 ]] ; then
exit 0
fi

# replace
trash $1
mv $1".opt.mp4" $1
kdialog --passivepopup "Done" 1

效果如下:

对话框

源码已经放到Github上了。