|
|
硬解硬编都不行 只要开qsv就报错 只能CPU软编 一切显示正常 我用的命令是这个:
# 1. 先杀掉当前正在运行的慢转码进程
pkill -f auto_compress_h265.sh
sleep 1
# 2. 覆盖硬编优化版脚本(画质参数完全不变)
cat > /vol1/1000/auto_compress_h265.sh <<'EOF'
#!/bin/bash
# 飞牛OS Intel N150 xxh3-64去重版 | 硬编优先优化版 | 画质参数完全不变
# 核心规则:H265原文件完全不处理 | 转码成功直接替换 | 临时文件用完即删
# 画质保证:CRF=20 完全保留,软编参数和原脚本一致,仅优化硬编兼容性
# ===================== 可自定义配置项 =====================
SCAN_DIRS=(
"/vol1/1000"
)
SCAN_RECURSIVE=true
THREADS_PER_TASK=4
CRF=20
# ==========================================================
# 基础配置
MIN_SIZE_M=1
MIN_SIZE_B=$((MIN_SIZE_M * 1024 * 1024))
LOW_BITRATE=500000
SCRIPT_PATH=$(readlink -f "$0")
LOG_FILE="${SCRIPT_PATH%.*}.log"
TMP_DIR="/vol1/1000/tmp"
TRANSCODE_MASTER="${TMP_DIR}/transcode_master.mp4"
# 依赖检查+自动创建临时目录
check_deps() {
# 自动创建临时目录,不存在就建,权限正常
mkdir -p "$TMP_DIR"
chmod 755 "$TMP_DIR"
# 检查必需依赖
local deps=("ffprobe" "ffmpeg" "xxhsum")
for dep in "${deps[@]}"; do
if ! command -v "$dep" &>/dev/null; then
echo "[$(date)] 错误:缺少必需依赖 $dep,请先安装" >> "$LOG_FILE"
exit 1
fi
done
}
# 判断是否为H265/HEVC编码
is_h265_file() {
local file="$1"
local codec=$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$file" 2>/dev/null)
[[ "$codec" == "hevc" || "$codec" == "h265" ]]
}
# 正确提取xxh3-64哈希值
get_file_hash() {
local file="$1"
xxhsum -H3 "$file" 2>/dev/null | awk -F'=' '{print $2}' | tr -d ' '
}
# 转码母版函数(硬编优先优化版,画质参数完全不变)
transcode_to_master() {
local source_file="$1"
local master_file="$2"
local tmp_master="${master_file}.tmp"
echo "[$(date)] 开始转码母版文件:$source_file" >> "$LOG_FILE"
# 读取视频参数
local br=$(ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "$source_file" 2>/dev/null || echo 0)
local is_4k_hdr=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,color_transfer,color_space -of compact "$source_file" 2>/dev/null | grep -qE '3840|smpte2084|hlg|bt2020' && echo 1 || echo 0)
# 色彩参数不变
local csp_arg="-color_primaries bt709 -color_trc bt709 -colorspace bt709"
[ "$is_4k_hdr" -eq 1 ] && csp_arg="-color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020"
# ✅ 核心优化:硬编兼容性拉满,不强制解码器,避免非H264视频解码失败
local common_args=(
-hwaccel qsv
-hwaccel_output_format nv12
-i "$source_file"
-map 0
-c:a copy
-c:s mov_text
-movflags +faststart
)
# ✅ 硬编参数:CRF=20完全保留,和原脚本画质一致,preset适配QSV提速
local qsv_vencode=(
-c:v hevc_qsv
-preset veryfast
-crf "$CRF"
-threads "$THREADS_PER_TASK"
-vf "vpp_qsv=deinterlace=0"
)
# ✅ 软编fallback:完全和原脚本参数一致,画质压缩率丝毫不改
local cpu_vencode=(
-c:v libx265
-preset fast
-crf "$CRF"
-threads "$THREADS_PER_TASK"
)
local transcode_success=0
echo "[$(date)] 优先使用Intel QSV核显硬编" >> "$LOG_FILE"
# 优先硬编
if ffmpeg -y "${common_args[@]}" "${qsv_vencode[@]}" $csp_arg -f mp4 "$tmp_master" >> "$LOG_FILE" 2>&1; then
transcode_success=1
echo "[$(date)] QSV硬编成功" >> "$LOG_FILE"
else
rm -f "$tmp_master"
echo "[$(date)] QSV硬编失败,切换原参数软编(画质完全不变)" >> "$LOG_FILE"
# 硬编失败才fallback,软编参数和你原脚本100%一致
if ffmpeg -y -i "$source_file" \
-map 0 -c:a copy -c:s mov_text \
"${cpu_vencode[@]}" \
-movflags +faststart $csp_arg -f mp4 "$tmp_master" >> "$LOG_FILE" 2>&1; then
transcode_success=1
else
rm -f "$tmp_master"
echo "[$(date)] 母版转码失败,跳过整组文件:$source_file" >> "$LOG_FILE"
fi
fi
if [ $transcode_success -eq 1 ]; then
mv -f "$tmp_master" "$master_file"
echo "[$(date)] 母版转码完成:$master_file" >> "$LOG_FILE"
return 0
else
return 1
fi
}
# 主程序
main() {
check_deps
echo "[$(date)] ========== 转码任务启动(硬编优先版,CRF=20画质不变)==========" >> "$LOG_FILE"
# 扫描视频文件
local find_args=(-type f \(
-iname "*.mp4" -o -iname "*.mkv" -o -iname "*.ts" -o -iname "*.mov"
-o -iname "*.avi" -o -iname "*.flv" -o -iname "*.wmv" -o -iname "*.m4v"
\))
local all_files=()
for dir in "${SCAN_DIRS[@]}"; do
if [ ! -d "$dir" ]; then
echo "[$(date)] 警告:目录不存在,跳过:$dir" >> "$LOG_FILE"
continue
fi
while IFS= read -r file; do
local size=$(stat -c "%s" "$file" 2>/dev/null || echo 0)
[ "$size" -ge "$MIN_SIZE_B" ] && all_files+=("$file")
done < <(find "$dir" "${find_args[@]}" 2>/dev/null | sort)
done
if [ ${#all_files[@]} -eq 0 ]; then
echo "[$(date)] 未找到符合条件的视频文件,任务结束" >> "$LOG_FILE"
echo "[$(date)] ========== 任务完成 ==========" >> "$LOG_FILE"
exit 0
fi
echo "[$(date)] 扫描完成,共找到 ${#all_files[@]} 个符合条件的视频文件" >> "$LOG_FILE"
# 按Hash分组重复文件
echo "[$(date)] 开始计算文件Hash,分组重复文件..." >> "$LOG_FILE"
declare -A hash_file_map
for file in "${all_files[@]}"; do
hash=$(get_file_hash "$file")
[ -n "$hash" ] && hash_file_map["$hash"]+="$file"$'\n'
done
local total_groups=${#hash_file_map[@]}
local current_group=0
echo "[$(date)] Hash分组完成,共 $total_groups 组独立视频文件" >> "$LOG_FILE"
# 循环处理每组文件
for hash in "${!hash_file_map[@]}"; do
current_group=$((current_group + 1))
mapfile -t file_list < <(echo -n "${hash_file_map[$hash]}" | grep -v '^$')
local file_count=${#file_list[@]}
echo "[$(date)] 正在处理第 $current_group/$total_groups 组,Hash:${hash:0:8}...,共 $file_count 个重复文件" >> "$LOG_FILE"
# 本组有H265文件,直接跳过
local has_h265=0
for file in "${file_list[@]}"; do
if is_h265_file "$file"; then
has_h265=1
break
fi
done
if [ $has_h265 -eq 1 ]; then
echo "[$(date)] 本组包含H265视频,整组跳过不处理" >> "$LOG_FILE"
continue
fi
# 转码母版
local source_file="${file_list[0]}"
rm -f "$TRANSCODE_MASTER" "${TRANSCODE_MASTER}.tmp"
if ! transcode_to_master "$source_file" "$TRANSCODE_MASTER"; then
rm -f "$TRANSCODE_MASTER" "${TRANSCODE_MASTER}.tmp"
continue
fi
# 批量替换本组所有文件
echo "[$(date)] 开始替换本组所有 $file_count 个文件" >> "$LOG_FILE"
for target_file in "${file_list[@]}"; do
local out_file="${target_file%.*}.mp4"
local tmp_out="${out_file}.tmp"
if cp -f "$TRANSCODE_MASTER" "$tmp_out"; then
rm -f "$target_file"
mv -f "$tmp_out" "$out_file"
echo "[$(date)] 替换完成:$out_file" >> "$LOG_FILE"
else
rm -f "$tmp_out"
echo "[$(date)] 替换失败,原文件保持不变:$target_file" >> "$LOG_FILE"
fi
done
# 本组处理完立刻清理临时文件
rm -f "$TRANSCODE_MASTER" "${TRANSCODE_MASTER}.tmp"
echo "[$(date)] 本组处理完成,临时文件已清理" >> "$LOG_FILE"
done
# 最终全局清理
unset hash_file_map
rm -f "$TRANSCODE_MASTER" "${TRANSCODE_MASTER}.tmp"
echo "[$(date)] ========== 所有文件处理完成,临时文件已全部清理 ==========" >> "$LOG_FILE"
}
main "$@"
EOF
# 3. 赋权并后台启动
chmod +x /vol1/1000/auto_compress_h265.sh
nohup bash /vol1/1000/auto_compress_h265.sh > /dev/null 2>&1 &
# 4. 输出启动结果
echo "✅ 硬编优化版脚本已后台启动,进程号:$!"
echo "📊 查看实时日志命令:tail -f /vol1/1000/auto_compress_h265.log"
echo "🔍 验证硬编是否生效:日志中出现「QSV硬编成功」即为核显加速正常工作"
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|