赞
踩
Android或者ios等手机上录制视频时,由于重力感应或者录制视频的摆放方式的问题会导致录制的视频拥有旋转信息。如果是横屏录制(手机逆时针旋转90度),则录制的视频时不带角度的。如果是竖屏录制(正常的拿手机的姿势),此时的录制的视频的旋转角度是90度。如果再旋转90度,此时一般音量键和关屏键朝下,此时的视频的旋转角度是180。以此类推。所以在手机上的视频一般会有4种角度的视频,播放时,要对视频资源进行旋转后再进行播放,不然视频就会出现各种反转、倾倒。
在https://www.stubbornhuang.com/1855/ 已经分享了在python中如何读取视频旋转角度并根据视频旋转角度旋转视频帧的代码,有兴趣的可以查看。
我们可以使用ffmpge下的工具ffprobe查看视频的元数据信息:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'a.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 creation_time : 2021-07-17T14:12:45.000000Z location : +28.7793+113.2697/ location-eng : +28.7793+113.2697/ com.android.version: 8.1.0 Duration: 00:00:06.13, start: 0.000000, bitrate: 18162 kb/s Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, smpte170m), 1920x1080, 17008 kb/s, SAR 1:1 DAR 16:9, 29.86 fps, 30 tbr, 90k tbn, 180k tbc (default) Metadata: creation_time : 2021-07-17T14:12:45.000000Z handler_name : VideoHandle Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 96 kb/s (default) Metadata: creation_time : 2021-07-17T14:12:45.000000Z handler_name : SoundHandle
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'b.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 creation_time : 2021-08-20T05:32:36.000000Z location : +00.0000+000.0000/ location-eng : +00.0000+000.0000/ com.android.version: 10 Duration: 00:00:03.89, start: 0.000000, bitrate: 8777 kb/s Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default) Metadata: creation_time : 2021-08-20T05:32:36.000000Z handler_name : SoundHandle Stream #0:1(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, unknown/bt470bg/unknown), 720x1280, 8724 kb/s, SAR 1:1 DAR 9:16, 30.09 fps, 30 tbr, 90k tbn, 180k tbc (default) Metadata: rotate : 90 creation_time : 2021-08-20T05:32:36.000000Z handler_name : VideoHandle Side data: displaymatrix: rotation of -90.00 degrees
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'c.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 creation_time : 2021-07-18T01:43:43.000000Z com.android.version: 10 Duration: 00:00:04.98, start: 0.000000, bitrate: 4997 kb/s Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080, 3502 kb/s, SAR 1:1 DAR 16:9, 29.12 fps, 29.50 tbr, 90k tbn, 180k tbc (default) Metadata: rotate : 180 creation_time : 2021-07-18T01:43:43.000000Z handler_name : VideoHandle Side data: displaymatrix: rotation of -180.00 degrees Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 193 kb/s (default) Metadata: creation_time : 2021-07-18T01:43:43.000000Z handler_name : SoundHandle
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'd.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 creation_time : 2021-10-29T01:52:22.000000Z location : +28.2386+113.0239/ location-eng : +28.2386+113.0239/ com.android.version: 11 Duration: 00:00:06.15, start: 0.000000, bitrate: 19144 kb/s Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1080x1920, 18490 kb/s, SAR 1:1 DAR 9:16, 30.08 fps, 90k tbr, 90k tbn, 180k tbc (default) Metadata: rotate : 270 creation_time : 2021-10-29T01:52:22.000000Z handler_name : VideoHandle Side data: displaymatrix: rotation of 90.00 degrees Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default) Metadata: creation_time : 2021-10-29T01:52:22.000000Z handler_name : SoundHandle
从上面各种视频的元数据信息中我们可以看到,如果该视频拥有旋转信息,那么在该视频的视频流的元数据信息的rotate字段会存储旋转角度,例如:
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1080x1920, 18490 kb/s, SAR 1:1 DAR 9:16, 30.08 fps, 90k tbr, 90k tbn, 180k tbc (default)
Metadata:
rotate : 270
creation_time : 2021-10-29T01:52:22.000000Z
handler_name : VideoHandle
之前查看的视频旋转角度是使用ffprobe的这个工具,但是如何在代码中使用ffmpeg sdk获取视频角度信息呢?
通过上述发现,视频的旋转角度存储在视频流的元数据中,所以我们首先可以打开视频文件,然后找到视频中的视频流,最后获取视频流的元数据信息并得到旋转角度,具体的代码如下:
double GetVideoRotationMetadataInfo(const std::string& video_path) { double rotationResult = 0.0; AVFormatContext* format_ctx = NULL; AVDictionaryEntry* tag = NULL; int ret; if ((ret = avformat_open_input(&format_ctx, video_path.c_str(), NULL, NULL))) return ret; // 查找文件视频流信息 int video_stream_idx = -1; for (int i = 0; i < format_ctx->nb_streams; ++i) { if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream_idx = i
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。