Pr——保存裁剪过后的视频(去除黑边)

通过文件->导出->媒体,使用快捷键CTRL+M,选择剪裁并设置为H.264格式,记录裁剪区域像素,取消固定宽高比,调整尺寸与裁剪区域一致,然后导出为.mp4文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

版本:Pr2022

问题描述:

我只想要红色标记的那块区域的视频画面。(相当于去除黑边问题)

问题解决:

1.点击文件—>导出—>媒体,(或者直接快捷键CTRL+M)

2.选择源,点击剪裁图标。(到处格式建议设置为H.264,导出的就是.mp4文件)

 3.裁剪出你想要的区域,鼠标放进这个框框中会显示这个裁剪区域的像素大小,记好这个数据! 

4.在导出设置中,修改基本视频设置,先取消勾选,之后取消 固定宽高比例,之后就可以任意调节宽度和高度了,使宽度与高度和你剪裁的区域的视频像素值保存一致。

5.直接导出就可以啦。

<think>好的,用户想了解黑马点评系统的双层拦截器设计与实现。我需要先理解双层拦截器的概念,以及它在黑马点评中的具体应用场景。根据用户提供的引用内容,特别是引用[5]提到的session和Redis的key处理,可能涉及到用户会话管理和缓存。 首先,双层拦截器可能指的是两个不同层次的拦截器,比如第一层处理登录验证,第二层处理其他业务逻辑,如刷新令牌有效期。例如,第一个拦截器检查用户是否登录,如果未登录则拦截请求;第二个拦截器在用户已登录的情况下,更新token的有效期,避免重复刷新。 接下来要考虑如何实现这两个拦截器。根据引用[3],第三方bean注入可能需要使用构造参数的方式,这可能涉及到拦截器的注册和依赖注入。例如,在Spring中,拦截器可能需要通过配置类添加,并且可能依赖Redis等组件来操作token。 然后,需要考虑拦截器的顺序,确保登录验证先于其他处理。同时,要处理静态资源放行,避免拦截不必要的请求。引用[4]提到QT的跨平台特性,虽然不直接相关,但可能提示系统设计时需要考虑不同环境下的兼容性。 另外,引用[5]提到使用String结构存储session,但需要注意key的唯一性,避免冲突。这可能涉及到在拦截器中从Redis获取用户信息,并判断token的有效期,进行刷新操作。 最后,需要验证设计的正确性,比如测试拦截器是否按顺序执行,以及token刷新逻辑是否正确。同时,生成相关问题,帮助用户深入理解,比如优化方法、异常处理、与网关过滤器的区别等。</think>### 黑马点评双层拦截器设计解析 #### 设计目标 双层拦截器主要用于实现**登录状态验证**和**令牌续期解耦**,典型场景: 1. 第一层拦截器:验证用户登录状态,未登录直接拦截请求[^5] 2. 第二层拦截器:已登录状态下,更新Redis中token有效期(避免重复刷新) #### 核心实现步骤 1. **拦截器定义** ```java // 登录校验拦截器(第一层) public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 从ThreadLocal或Redis获取用户信息(引用[5]的会话存储方案) if (UserHolder.getUser() == null) { response.setStatus(401); return false; } return true; } } // Token续期拦截器(第二层) public class RefreshTokenInterceptor implements HandlerInterceptor { private StringRedisTemplate redisTemplate; // 使用构造器注入第三方Bean(引用[3]的注入方式) public RefreshTokenInterceptor(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("authorization"); if (StrUtil.isNotBlank(token)) { Map<Object, Object> userMap = redisTemplate.opsForHash().entries("login:token:" + token); if (!userMap.isEmpty()) { UserHolder.saveUser(BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false)); redisTemplate.expire("login:token:" + token, 30, TimeUnit.MINUTES); // 续期操作 } } return true; } } ``` 2. **拦截器注册配置** ```java @Configuration public class MvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 先添加的拦截器会后执行(栈结构) registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)) .addPathPatterns("/**") .order(0); registry.addInterceptor(new LoginInterceptor()) .excludePathPatterns( "/shop/**", "/voucher/**", "/upload/**", "/blog/hot", "/user/code", "/user/login" ).order(1); } } ``` #### 关键设计点 1. **执行顺序控制**:通过`order()`方法设置优先级,数值越小优先级越高 2. **路径过滤模式**:`excludePathPatterns`放行无需登录的接口 3. **线程上下文存储**:使用`UserHolder`(基于ThreadLocal)存储用户信息 4. **Redis存储结构**:采用Hash结构存储用户信息(引用[5]的会话处理改进方案) #### 验证测试案例 ```java @SpringBootTest public class InterceptorTest { @Autowired private MockMvc mockMvc; @Test void testTokenRefresh() throws Exception { // 1. 生成测试token String token = "test_token_123"; // 2. 写入Redis初始有效期 redisTemplate.opsForHash().put("login:token:" + token, "id", "10001"); redisTemplate.expire("login:token:" + token, 5, TimeUnit.MINUTES); // 3. 发送携带token的请求 mockMvc.perform(get("/user/me") .header("authorization", token)) .andExpect(status().isOk()); // 4. 验证Redis有效期是否延长到30分钟 Long expire = redisTemplate.getExpire("login:token:" + token, TimeUnit.SECONDS); assertThat(expire).isGreaterThan(29 * 60); // 误差允许范围内 } } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值