You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GStreamer中aesenc/aesdec写入文件后解密播放失败问题求助

GStreamer AES加密视频后写入文件无法播放的问题

问题现象

  1. 单管道加密+解密播放可正常执行:
gst-launch-1.0 filesrc location=test-plain.mp4 ! aesenc key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 ! aesdec key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 ! queue ! decodebin ! autovideosink
  1. 分两步操作(加密写入文件→读取解密播放)时失败:
    加密命令:
gst-launch-1.0 filesrc location=test-plain.mp4 ! aesenc key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 ! filesink location=test.enc

播放命令:

gst-launch-1.0 filesrc location=test.enc ! aesdec key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 ! queue ! decodebin ! autovideosink

触发错误:

ERROR: from element /GstPipeline:pipeline0/GstAesDec:aesdec0: Corrupt cipher text.
Additional debug info:
../ext/aes/gstaesdec.c(494): gst_aes_dec_transform (): /GstPipeline:pipeline0/GstAesDec:aesdec0:
Illegal PKCS7 padding value 183
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
ERROR: from element /GstPipeline:pipeline0/GstFileSrc:filesrc0: Internal data stream error.
Additional debug info:
../libs/gst/base/gstbasesrc.c(3127): gst_base_src_loop (): /GstPipeline:pipeline0/GstFileSrc:filesrc0:
streaming stopped, reason error (-5)
ERROR: pipeline doesn't want to preroll.
ERROR: from element /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind: Stream doesn't contain enough data.
Additional debug info:
../plugins/elements/gsttypefindelement.c(1014): gst_type_find_element_chain_do_typefinding (): /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind:
Can't typefind stream
  1. 添加per-buffer-padding=false参数后,播放仍失败,但解密后写入文件可正常播放:
    播放命令:
gst-launch-1.0 -v filesrc location=test-aes-pbp-off.enc ! aesdec key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 per-buffer-padding=false ! decodebin ! autovideosink

错误信息:

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:src: caps = video/mpeg, systemstream=(boolean)false, mpegversion=(int)4, parsed=(boolean)false
/GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstTypeFindElement:typefind.GstPad:src: caps = NULL
ERROR: from element /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMpeg4VParse:mpeg4vparse0: No valid frames found before end of stream
Additional debug info:
../libs/gst/base/gstbaseparse.c(3673): gst_base_parse_loop (): /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstMpeg4VParse:mpeg4vparse0

原因分析

  • 默认aesenc会给每个GstBuffer添加PKCS7填充,保证数据长度符合AES的16字节块大小。但加密数据写入文件后,原buffer的边界信息丢失,解密时会把填充数据当成视频流的一部分,导致解密后数据损坏,触发填充校验错误。
  • 关闭per-buffer-padding后,虽然没有额外填充,但decodebin预滚阶段需要足够初始数据识别流格式。直接播放时,解密后的流缺少MP4容器的元数据,或数据块不完整,导致解析器找不到有效帧;而写入文件后再播放,文件保留了完整流结构,就能正常识别。

解决方案

方案1:明确指定流格式+关闭按buffer填充

加密时先解封装MP4,提取视频流后加密,同时关闭按buffer填充:

gst-launch-1.0 filesrc location=test-plain.mp4 ! qtdemux ! h264parse ! capsfilter caps="video/x-h264, stream-format=(string)avc, alignment=(string)au" ! aesenc key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 per-buffer-padding=false ! filesink location=test-encrypted.h264

播放时同样关闭填充,并指定解密后的流格式,帮助decodebin识别:

gst-launch-1.0 filesrc location=test-encrypted.h264 ! aesdec key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 per-buffer-padding=false ! capsfilter caps="video/x-h264, stream-format=(string)avc, alignment=(string)au" ! h264parse ! avdec_h264 ! autovideosink

方案2:用容器封装加密后的流

将加密后的流重新封装进MP4容器,保留元数据信息:
加密命令:

gst-launch-1.0 filesrc location=test-plain.mp4 ! qtdemux name=d d.video_0 ! h264parse ! aesenc key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 per-buffer-padding=false ! mp4mux ! filesink location=test-encrypted.mp4

播放命令:

gst-launch-1.0 filesrc location=test-encrypted.mp4 ! qtdemux name=d d.video_0 ! aesdec key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 per-buffer-padding=false ! h264parse ! avdec_h264 ! autovideosink

方案3:使用GStreamer专用AES复用器/解复用器

用aesgstmux/aesgstdemux处理加密流,自动管理buffer边界和填充:
加密命令:

gst-launch-1.0 filesrc location=test-plain.mp4 ! qtdemux ! h264parse ! aesenc key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 ! aesgstmux ! filesink location=test-encrypted.gstaes

播放命令:

gst-launch-1.0 filesrc location=test-encrypted.gstaes ! aesgstdemux ! aesdec key=1f9423681beb9a79215820f6bda73d0f iv=e9aa8e834d8d70b7e0d254ff670dd718 ! h264parse ! avdec_h264 ! autovideosink

内容的提问来源于stack exchange,提问作者user2177594

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:31:01