Last active
October 7, 2024 16:18
-
-
Save tsukumijima/62b7aea32aeb9205c9616fbae018c4b1 to your computer and use it in GitHub Desktop.
Rockchip RK3588S (NanoPi R6S) でテレビの MPEG-TS を HW デコード + HW エンコードで H.264 / H.265 な MPEG-TS にトランスコードするシェルスクリプト (代わりに https://github.com/rigaya/rkmppenc を使うことをおすすめします)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Usage: rk3588-rec-enc.sh <ID: example: 3273601024> <dst.ts> | |
# | |
# Requirements: | |
# - Mirakurun | |
# - ffmpeg | |
# - tsreadex (https://github.com/xtne6f/tsreadex) | |
# - gstreamer | |
# - gstreamer-plugins-base | |
# - gstreamer-plugins-good | |
# - gstreamer-plugins-bad | |
# - gstreamer-plugins-ugly | |
# - gstreamer-plugins-libav | |
# - gstreamer-rockchip (https://github.com/JeffyCN/rockchip_mirrors/tree/gstreamer-rockchip) | |
# - mpp (https://github.com/rockchip-linux/mpp) | |
# ID List: | |
# - NHK総合: 3273601024 | |
# - NHKEテレ: 3273701032 | |
# - tvk: 3237524632 | |
# - 日テレ: 3273801040 | |
# - テレ朝: 3274101064 | |
# - TBS: 3273901048 | |
# - テレ東: 3274201072 | |
# - フジ: 3274001056 | |
# - TOKYO MX: 3239123608 | |
# - NHK BS1: 400101 | |
# - NHK BSプレミアム: 400103 | |
# - BS日テレ: 400141 | |
# - BS朝日: 400151 | |
# - BS-TBS: 400161 | |
# - BSテレ東: 400171 | |
# - BSフジ: 400181 | |
# - BS11: 400211 | |
# - BS12: 400222 | |
# 既知の問題: | |
# - BS チャンネル全般でしばしば HW デコードに失敗することがある (mppvideodec の "failed to send packet" / "can't handle this frame" エラー) | |
# - tsreadex で ARIB 字幕を変換した Timed ID3 Metadata (timed_id3) を挿入しているが、FFmpeg と異なり GStreamer には Timed ID3 Metadata を | |
# コピーする機能がないため、エンコード後の TS には Timed ID3 Metadata が含まれていない (GStreamer の改造が必要そう…) | |
# - GStreamer のインターレース解除 Element (deinterlace) は BOB 化 (60fps 化) に対応していない | |
# - 調整を繰り返してなんとか動作しているもので、柔軟性が皆無 | |
# 定数 | |
MIRAKURUN_HOST=http://192.168.1.28:40772 | |
IS_SW_DECODE=0 # 0: HW デコード, 1: SW デコード | |
IS_H265=0 # 0: H.264, 1: H.265 | |
VIDEO_WIDTH=1440 | |
VIDEO_HEIGHT=1080 | |
VIDEO_BITRATE=9500000 | |
VIDEO_GOP=15 | |
VIDEO_BITRATE_MAX=13000000 | |
AUDIO_BITRATE=192000 | |
AUDIO_SAMPLERATE=48000 | |
AUDIO_VOLUME=2.0 | |
# HW デコードと SW デコードでデコーダーを切り替える | |
if [ ${IS_SW_DECODE} -eq 1 ]; then | |
DECODER="mpeg2dec discard-corrupted-frames=true max-errors=1000" | |
else | |
DECODER="mppvideodec arm-afbc=true discard-corrupted-frames=true max-errors=1000" | |
fi | |
# H.264 と H.265 でエンコーダーを切り替える | |
if [ ${IS_H265} -eq 1 ]; then | |
ENCODER="mpph265enc width=${VIDEO_WIDTH} height=${VIDEO_HEIGHT} bps=${VIDEO_BITRATE} bps-max=${VIDEO_BITRATE_MAX} \ | |
rc-mode=vbr gop=${VIDEO_GOP} ! h265parse" | |
# 1440×1080 のときだけ、SAR を 4:3 にして 16:9 に引き伸ばす | |
if [ ${VIDEO_WIDTH} -eq 1440 ] && [ ${VIDEO_HEIGHT} -eq 1080 ]; then | |
BSF="-bsf:v hevc_metadata=sample_aspect_ratio=4/3" | |
else | |
BSF="" | |
fi | |
else | |
ENCODER="mpph264enc width=${VIDEO_WIDTH} height=${VIDEO_HEIGHT} bps=${VIDEO_BITRATE} bps-max=${VIDEO_BITRATE_MAX} \ | |
profile=main rc-mode=vbr gop=${VIDEO_GOP} ! h264parse" | |
# 1440×1080 のときだけ、SAR を 4:3 にして 16:9 に引き伸ばす | |
if [ ${VIDEO_WIDTH} -eq 1440 ] && [ ${VIDEO_HEIGHT} -eq 1080 ]; then | |
BSF="-bsf:v h264_metadata=sample_aspect_ratio=4/3" | |
else | |
BSF="" | |
fi | |
fi | |
curl --silent ${MIRAKURUN_HOST}/api/services/${1}/stream | \ | |
tsreadex -x 18/38/39 -n -1 -a 13 -b 5 -c 1 -u 1 -d 13 - | \ | |
ffmpeg -f mpegts -analyzeduration 500000 -i pipe:0 -map 0:v:0 -map 0:a:0 -map 0:a:1 -map 0:d? -ignore_unknown \ | |
-fflags nobuffer -flags low_delay -max_delay 250000 -max_interleave_delta 100K -threads auto \ | |
-vcodec copy -acodec copy -y -f mpegts pipe:1 | \ | |
GST_DEBUG=FIXME gst-launch-1.0 --eos-on-shutdown fdsrc ! tsdemux name=demux \ | |
demux. ! queue ! mpegvideoparse ! ${DECODER} ! deinterlace fields=auto method=yadif mode=auto ! ${ENCODER} ! mux. \ | |
demux. ! queue ! avdec_aac max-errors=1000 ! audioconvert ! volume volume=${AUDIO_VOLUME} ! \ | |
avenc_aac aac-coder=twoloop ac=2 bitrate=${AUDIO_BITRATE} ar=${AUDIO_SAMPLERATE} ! mux. \ | |
demux. ! queue ! avdec_aac max-errors=1000 ! audioconvert ! volume volume=${AUDIO_VOLUME} ! \ | |
avenc_aac aac-coder=twoloop ac=2 bitrate=${AUDIO_BITRATE} ar=${AUDIO_SAMPLERATE} ! mux. \ | |
mpegtsmux name=mux ! progressreport update-freq=1 ! filesink buffer-mode=unbuffered location=/dev/stdout | | |
ffmpeg -f mpegts -analyzeduration 500000 -i pipe:0 -map 0:v:0 -map 0:a:0 -map 0:a:1 -map 0:d? -ignore_unknown \ | |
-fflags nobuffer -flags low_delay -max_delay 250000 -max_interleave_delta 100K -threads auto \ | |
-aspect 16:9 -c copy ${BSF} -y -f mpegts pipe:1 > ${2} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment