uni-app 压缩竖屏拍摄的视频就会旋转

uni-app 压缩竖屏拍摄的视频就会旋转

产品分类:

uniapp/App

PC开发环境操作系统:

Mac

PC开发环境操作系统版本号:

15.6.1

HBuilderX类型:

正式

HBuilderX版本号:

4.76

手机系统:

iOS

手机系统版本号:

iOS 16

手机厂商:

苹果

手机机型:

iPhoneX

页面类型:

vue

vue版本:

vue3

打包方式:

云端

项目创建方式:

HBuilderX

示例代码:

<template>  
    <view class="content">  
        <view class="header">  
            <text class="title">视频压缩测试</text>  
        </view>  

        <!-- 选择视频按钮 -->  
        <view class="btn-section">  
            <button type="primary" @click="selectVideo" :disabled="loading">选择视频</button>  
        </view>  

        <!-- 视频信息显示 -->  
        <view class="video-info" v-if="selectedVideo">  
            <text class="section-title">原始视频信息</text>  
            <view class="info-item">  
                <text class="info-label">路径:</text>  
                <text class="info-value">{{ selectedVideo.tempFilePath }}</text>  
            </view>  
            <view class="info-item" v-if="selectedVideo.size">  
                <text class="info-label">大小:</text>  
                <text class="info-value">{{ formatFileSize(selectedVideo.size) }}</text>  
            </view>  
            <view class="info-item" v-if="selectedVideo.duration">  
                <text class="info-label">时长:</text>  
                <text class="info-value">{{ formatDuration(selectedVideo.duration) }}</text>  
            </view>  
            <view class="info-item" v-if="selectedVideo.width && selectedVideo.height">  
                <text class="info-label">分辨率:</text>  
                <text class="info-value">{{ selectedVideo.width }}x{{ selectedVideo.height }}</text>  
            </view>  
            <view class="info-item" v-if="originalVideoInfo">  
                <text class="info-label">方向:</text>  
                <text class="info-value">{{ originalVideoInfo.orientation }}</text>  
            </view>  
        </view>  

        <!-- 压缩选项 -->  
        <view class="compress-options" v-if="selectedVideo">  
            <text class="section-title">压缩选项</text>  
            <view class="option-group">  
                <text class="option-label">压缩质量:</text>  
                <radio-group @change="onQualityChange">  
                    <label class="radio-item">  
                        <radio value="low" :checked="compressOptions.quality === 'low'" />  
                        <text>低质量</text>  
                    </label>  
                    <label class="radio-item">  
                        <radio value="medium" :checked="compressOptions.quality === 'medium'" />  
                        <text>中等质量</text>  
                    </label>  
                    <label class="radio-item">  
                        <radio value="high" :checked="compressOptions.quality === 'high'" />  
                        <text>高质量</text>  
                    </label>  
                </radio-group>  
            </view>  
        </view>  

        <!-- 压缩按钮 -->  
        <view class="btn-section" v-if="selectedVideo">  
            <button type="primary" @click="compressVideo" :disabled="loading">  
                {{ loading ? '压缩中...' : '开始压缩' }}  
            </button>  
        </view>  

        <!-- 加载状态 -->  
        <view class="loading" v-if="loading">  
            <text>{{ loadingText }}</text>  
        </view>  

        <!-- 压缩结果 -->  
        <view class="compress-result" v-if="compressResult">  
            <text class="section-title">压缩结果</text>  

            <!-- 视频预览对比 -->  
            <view class="video-preview-section">  
                <text class="preview-title">视频预览对比</text>  
                <view class="video-compare">  
                    <!-- 原始视频预览 -->  
                    <view class="video-item">  
                        <text class="video-label">原始视频</text>  
                        <video   
                            :src="selectedVideo.tempFilePath"  
                            class="preview-video"  
                            controls  
                            :show-center-play-btn="true"  
                            :show-fullscreen-btn="true"  
                            :enable-progress-gesture="true"  
                        ></video>  
                        <view class="video-info-summary">  
                            <text class="size-text">{{ formatFileSize(compressResult.originalSize) }}</text>  
                            <text class="resolution-text" v-if="originalVideoInfo">  
                                {{ originalVideoInfo.width }}x{{ originalVideoInfo.height }}  
                            </text>  
                            <text class="orientation-text" v-if="originalVideoInfo">  
                                {{ originalVideoInfo.orientation }}  
                            </text>  
                        </view>  
                    </view>  

                    <!-- 压缩后视频预览 -->  
                    <view class="video-item">  
                        <text class="video-label">压缩后视频</text>  
                        <video   
                            :src="compressResult.compressedPath"  
                            class="preview-video"  
                            controls  
                            :show-center-play-btn="true"  
                            :show-fullscreen-btn="true"  
                            :enable-progress-gesture="true"  
                        ></video>  
                        <view class="video-info-summary">  
                            <text class="size-text">{{ formatFileSize(compressResult.compressedSize) }}</text>  
                            <text class="resolution-text" v-if="compressResult.compressedVideoInfo">  
                                {{ compressResult.compressedVideoInfo.width }}x{{ compressResult.compressedVideoInfo.height }}  
                            </text>  
                            <text class="orientation-text" v-if="compressResult.compressedVideoInfo">  
                                {{ compressResult.compressedVideoInfo.orientation }}  
                            </text>  
                            <text class="compression-text">  
                                {{ calculateCompressionRatio(compressResult.originalSize, compressResult.compressedSize) }}  
                            </text>  
                        </view>  
                    </view>  
                </view>  
            </view>  

            <!-- 详细信息 -->  
            <view class="detail-info">  
                <view class="info-item">  
                    <text class="info-label">压缩后路径:</text>  
                    <text class="info-value">{{ compressResult.compressedPath }}</text>  
                </view>  
                <view class="info-item">  
                    <text class="info-label">文件大小:</text>  
                    <text class="info-value">  
                        {{ formatFileSize(compressResult.originalSize) }} →   
                        {{ formatFileSize(compressResult.compressedSize) }}  
                        ({{ calculateCompressionRatio(compressResult.originalSize, compressResult.compressedSize) }})  
                    </text>  
                </view>  
                <view class="info-item">  
                    <text class="info-label">压缩质量:</text>  
                    <text class="info-value">{{ compressResult.quality }}</text>  
                </view>  
                <view class="info-item">  
                    <text class="info-label">耗时:</text>  
                    <text class="info-value">{{ compressResult.duration }}ms</text>  
                </view>  
            </view>  
        </view>  

        <!-- 错误信息 -->  
        <view class="error-message" v-if="errorMessage">  
            <text class="error-text">{{ errorMessage }}</text>  
            <button type="default" size="mini" @click="clearError">清除</button>  
        </view>  
    </view>  
</template>  

操作步骤:

提供了800行的完整示例页面代码.可以直接代码在一个页面中复现,以及拍摄了完整的复现过程和录屏中使用的原视频.

预期结果:

常规操作应该是等比例处理? 但是目前明显能发现宽高似乎调转了. 竖屏压缩完应该还是竖屏.横屏应该还是横屏.

实际结果:

实际竖屏变成了横屏.

bug描述:

压缩竖屏拍摄的视频就会旋转.代码非常简单. 方向变化了. 而且宽高似乎?

{
    "压缩前": {
        "宽度": 1080,
        "高度": 1920,
        "方向": "right",
        "时长": 6,
        "比特率": 7801,
        "帧率": 30.00848,
        "格式": "video/mp4"
    },
    "压缩后": {
        "宽度": 960,
        "高度": 540,
        "方向": "up",
        "时长": 6,
        "比特率": 1517,
        "帧率": 30.00853,
        "格式": "video/mp4",
        "文件大小": 1193873
    }
}

这是压缩前后的uni.getVideoInfo获取对比.


更多关于uni-app 压缩竖屏拍摄的视频就会旋转的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app 压缩竖屏拍摄的视频就会旋转的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个已知的iOS平台视频压缩方向问题。当使用uni.compressVideo压缩竖屏拍摄的视频时,视频元数据中的方向信息可能未被正确处理,导致压缩后视频显示方向错误。

问题分析:

  1. 原始视频分辨率为1080x1920(竖屏),方向为"right"(顺时针旋转90度)
  2. 压缩后分辨率为960x540(横屏比例),方向变为"up"(正常方向)
  3. 压缩过程中,视频的实际方向信息丢失,导致播放器无法正确识别旋转角度

临时解决方案: 在压缩后手动处理视频方向:

// 获取压缩后视频信息
const videoInfo = await uni.getVideoInfo({
  src: compressedPath
});

// 如果检测到方向异常,可以使用canvas重绘或调用原生插件修正
if (videoInfo.orientation !== originalOrientation) {
  // 需要额外处理方向修正
}
回到顶部