我有一个MP4
DJI 无人机拍摄的视频文件。该文件包含视频流(H.264)以及两个数据流格式未知。我想将视频从 转换h.264
为h.265
并保存包含的两个数据流。遗憾的是,我无法强制FFmpeg将数据流从输入文件复制到输出文件。
以下是 mp4 文件(ffprobe DJI_0019.MP4
)的信息:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5631004c2730] stream 0, timescale not set
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'DJI_0019.MP4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
creation_time : replaced_timestamp
encoder : DJIMavic3
Duration: 00:01:05.66, start: 0.000000, bitrate: 128915 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 3840x2160, 127648 kb/s, 29.41 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
creation_time : replaced_timestamp
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Data: none (djmd / 0x646D6A64), 13 kb/s
Metadata:
creation_time : replaced_timestamp
handler_name : DJI meta
Stream #0:2(und): Data: none (dbgi / 0x69676264), 1190 kb/s
Metadata:
creation_time : replaced_timestamp
handler_name : DJI dbgi
Stream #0:3: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 960x540 [SAR 1:1 DAR 16:9], 90k tbr, 90k tbn, 90k tbc (attached pic)
Unsupported codec with id 0 for input stream 1
Unsupported codec with id 0 for input stream 2
我尝试了以下命令:
ffmpeg -i DJI_0019.MP4 -map 0 -c:v libx265 -crf 25 -c:d copy -copy_unknown DJI_0019.v2.MP4
该命令失败并出现以下错误。输出文件为空。
[mp4 @ 0x556d0180ced0] Could not find tag for codec none in stream #1, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:0 --
请注意,对于“-c:d”选项,我尝试了不同的建议值,但均未成功:
copy
none
bin
bin_data
data
null
file
同时,尝试使用以下命令将数据流保存到单独的文件中,成功:
ffmpeg -i DJI_0019.MP4 -map 0:d:0 -c copy -copy_unknown -f data DJI_0019.data0.bin
ffmpeg -i DJI_0019.MP4 -map 0:d:1 -c copy -copy_unknown -f data DJI_0019.data1.bin
问题:
如何强制 FFmpeg 将数据流从输入复制到输出?
这是 ffmpeg 的信息:
ffmpeg version 4.4.3 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 11.3.0 (Gentoo 11.3.0 p5)
configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64
--docdir=/usr/share/doc/ffmpeg-4.4.3/html --mandir=/usr/share/man --enable-shared
--cc=x86_64-pc-linux-gnu-gcc --cxx=x86_64-pc-linux-gnu-g++ --ar=x86_64-pc-linux-gnu-ar
--nm=x86_64-pc-linux-gnu-nm --strip=x86_64-pc-linux-gnu-strip
--ranlib=x86_64-pc-linux-gnu-ranlib --pkg-config=x86_64-pc-linux-gnu-pkg-config
--optflags='-O2 -pipe -march=native' --disable-static --enable-avfilter --enable-avresample
--disable-stripping --disable-optimizations --disable-libcelt --disable-indev=oss
--disable-indev=jack --disable-indev=sndio --disable-outdev=oss --disable-outdev=sndio
--enable-nonfree --enable-bzlib --disable-runtime-cpudetect --disable-debug --disable-gcrypt
--enable-gnutls --disable-gmp --enable-gpl --disable-hardcoded-tables --enable-iconv
--disable-libxml2 --disable-lzma --enable-network --disable-opencl --disable-openssl
--enable-postproc --disable-libsmbclient --enable-ffplay --enable-sdl2 --disable-vaapi
--disable-vdpau --disable-vulkan --enable-xlib --enable-libxcb --enable-libxcb-shm
--enable-libxcb-xfixes --enable-zlib --enable-libcdio --disable-libiec61883
--disable-libdc1394 --enable-libcaca --disable-openal --disable-opengl --enable-libv4l2
--disable-libpulse --disable-libdrm --disable-libjack --disable-libopencore-amrwb
--disable-libopencore-amrnb --disable-libcodec2 --enable-libdav1d --enable-libfdk-aac
--disable-libopenjpeg --disable-libbluray --disable-libgme --disable-libgsm
--disable-libaribb24 --disable-mmal --disable-libmodplug --disable-libopus
--disable-libilbc --disable-librtmp --disable-libssh --disable-libspeex --disable-libsrt
--disable-librsvg --disable-ffnvcodec --disable-libvorbis --disable-libvpx --disable-libzvbi
--disable-appkit --disable-libbs2b --disable-chromaprint --disable-cuda-llvm
--disable-libflite --disable-frei0r --disable-libvmaf --disable-libfribidi
--disable-fontconfig --disable-ladspa --enable-libass --disable-libtesseract
--disable-lv2 --disable-libfreetype --disable-libvidstab --disable-librubberband
--disable-libzmq --disable-libzimg --disable-libsoxr --enable-pthreads --disable-amf
--disable-libvo-amrwbenc --disable-libkvazaar --disable-libaom --enable-libmp3lame
--disable-libopenh264 --disable-librav1e --disable-libsnappy --disable-libsvtav1
--disable-libtheora --disable-libtwolame --disable-libwebp --enable-libx264 --enable-libx265
--enable-libxvid --disable-armv5te --disable-armv6 --disable-armv6t2 --disable-neon
--disable-vfp --disable-vfpv3 --disable-armv8 --disable-mipsdsp --disable-mipsdspr2
--disable-mipsfpu --disable-altivec --disable-vsx --disable-power8 --disable-amd3dnow
--disable-amd3dnowext --disable-aesni --disable-avx --disable-avx2 --disable-fma3
--disable-fma4 --disable-sse3 --disable-ssse3 --disable-sse4 --disable-sse42 --disable-xop
--cpu=host --disable-doc --disable-htmlpages --enable-manpages
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
答案1
看来 mp4 容器不接受数据流。
要使用数据流转换视频,您可以使用接受数据流的 mpeg-ts 容器。
要在 mpeg-ts 容器中录制:
ffmpeg -i <input> -map 0 -c copy -f mpegts record.ts
然后读取/提取数据内容
ffmpeg -i record.ts -map 0:1 -c copy -f data data1.txt
:
ffmpeg -i record.ts -map 0:2 -c copy -f data data2.txt
答案2
Sony 视频(h264 和 h265 编码文件,源自 ILCE-7M4)也存在此问题:MP4 包含实时元数据 (rtmd),ffmpeg 不允许直接复制(非常严格)。MP4Box 会为您完成此操作,因此您不一定需要将容器“移动”到 MOV 或 M4V。在下面的示例中,我使用 Apple 的 AAC 编码器和特定比特率(!= CRF)进行了 2 次转换:
ffmpeg -y -i "${INPUTFILE}" -c:v libx265 -b:v 35000k -x265-params pass=1 -an -f null /dev/null && \
ffmpeg -i "${INPUTFILE}" -c:v libx265 -b:v 35000k -x265-params pass=2 -c:a aac_at -b:a 192k -movflags use_metadata_tags+faststart -map_metadata 0 -tag:v hvc1 "${OUTPUTFILE}"
MP4Box -add ${INPUTFILE}#3 ${OUTPUTFILE}
MP4Box -dump-xml ${INPUTFILE}.xml ${INPUTFILE}
MP4Box -set-meta META -set-xml ${INPUTFILE}.xml ${OUTPUTFILE}