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

Ruby on Rails ActiveStorage仅显示视频首帧(206 Partial Content)

问题描述

当前行为

访问应用的/video页面时,仅显示视频第一帧,控制台输出Partial Content的GET请求,但无后续播放操作。

代码检视

视频页面HTML代码

<video autoplay=true type="video/mp4" src="<%=@redirectURL%>"/>

Rails控制器代码

class VideoController < ApplicationController
  def index
      ActiveStorage::Current.url_options =  "http://127.0.0.1:3000"
      if session[:user_id]
        @user = User.find(session[:user_id])
        @redirectURL = url_for(@user.video)
    end
  end
end

注册页面HTML代码

<h1>Sign up</h1>

<%= form_with model: @user, url: signup_path do |form|%>
<% if @user.errors.any? %>
    <div class="alert alert-danger">
    <% @user.errors.full_messages.each do |message| %>
        <div> <%= message %></div>
    <% end %>
<% end %>

<div class="mb-3">
    <%= form.label :email %>
    <%= form.text_field :email, class: "form-control", placeholder: "example@site.com"%>
</div>
<div class="mb-3">
    <%= form.label :password %>
    <%= form.password_field :password, class: "form-control", placeholder: "secretpassword123" %>
</div>
<div class="mb-3">
    <%= form.label :password_confirmation %>
    <%= form.password_field :password_confirmation, class: "form-control", placeholder: "secretpassword123" %>
</div>
<div class="input-group mb-3">
    <%= form.label :video, class: "input-group-text", for: "inputGroupFile01"%>
    <%= form.file_field :video, class: "form-control", id: "inputGroupFile01" %>
</div>
<div class="mb-3">
    <%= form.submit "Get Started!" , class: "btn btn-primary" %>
</div>
<% end %>

服务器日志

重定向请求日志

Started GET "/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--77812323ea618480d0497c73b1b1cb96856a585a/048496124_main_xxl.mp4" for 127.0.0.1 at 2023-05-04 23:24:24 -0400
Processing by ActiveStorage::Blobs::RedirectController#show as MP4
  Parameters: {"signed_id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--77812323ea618480d0497c73b1b1cb96856a585a", "filename"=>"048496124_main_xxl"}
  ActiveStorage::Blob Load (0.2ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]   
  Disk Storage (1.9ms) Generated URL for file at key: jpgplubo5jtvp1iefb02l82jlfdl (http://127.0.0.1:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhhbkJuY0d4MVltODFhblIyY0RGcFpXWmlNREpzT0RKcWJHWmtiQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpVzJGMGRHRmphRzFsYm5RN0lHWnBiR1Z1WVcxbFBTSXdORGcwT1RZeE1qUmZiV0ZwYmw5NGVHd3ViWEEwSWpzZ1ptbHNaVzVoYldVcVBWVlVSaTA0Snljd05EZzBPVFl4TWpSZmJXRnBibDk0ZUd3dWJYQTBCanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lPZG1sa1pXOHZiWEEwQmpzR1ZEb1JjMlZ5ZG1salpWOXVZVzFsT2dwc2IyTmhiQT09IiwiZXhwIjoiMjAyMy0wNS0wNVQwMzoyOToyNC4xMzlaIiwicHVyIjoiYmxvYl9rZXkifX0=--c56634c4ae269745a756dbc26f32cf373f99b0c9/048496124_main_xxl.mp4)
Redirected to http://127.0.0.1:3000/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhhbkJuY0d4MVltODFhblIyY0RGcFpXWmlNREpzT0RKcWJHWmtiQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpVzJGMGRHRmphRzFsYm5RN0lHWnBiR1Z1WVcxbFBTSXdORGcwT1RZeE1qUmZiV0ZwYmw5NGVHd3ViWEEwSWpzZ1ptbHNaVzVoYldVcVBWVlVSaTA0Snljd05EZzBPVFl4TWpSZmJXRnBibDk0ZUd3dWJYQTBCanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lPZG1sa1pXOHZiWEEwQmpzR1ZEb1JjMlZ5ZG1salpWOXVZVzFsT2dwc2IyTmhiQT09IiwiZXhwIjoiMjAyMy0wNS0wNVQwMzoyOToyNC4xMzlaIiwicHVyIjoiYmxvYl9rZXkifX0=--c56634c4ae269745a756dbc26f32cf373f99b0c9/048496124_main_xxl.mp4
Completed 302 Found in 8ms (ActiveRecord: 0.2ms | Allocations: 2139)

文件请求日志

Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhhbkJuY0d4MVltODFhblIyY0RGcFpXWmlNREpzT0RKcWJHWmtiQVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpVzJGMGRHRmphRzFsYm5RN0lHWnBiR1Z1WVcxbFBTSXdORGcwT1RZeE1qUmZiV0ZwYmw5NGVHd3ViWEEwSWpzZ1ptbHNaVzVoYldVcVBWVlVSaTA0Snljd05EZzBPVFl4TWpSZmJXRnBibDk0ZUd3dWJYQTBCanNHVkRvUlkyOXVkR1Z1ZEY5MGVYQmxTU0lPZG1sa1pXOHZiWEEwQmpzR1ZEb1JjMlZ5ZG1salpWOXVZVzFsT2dwc2IyTmhiQT09IiwiZXhwIjoiMjAyMy0wNS0wNVQwMzoyOToyNC4xMzlaIiwicHVyIjoiYmxvYl9rZXkifX0=--c56634c4ae269745a756dbc26f32cf373f99b0c9/048496124_main_xxl.mp4" for 127.0.0.1 at 2023-05-04 23:24:24 -0400
Processing by ActiveStorage::DiskController#show as MP4
  Parameters: {"encoded_key"=>"[FILTERED]", "filename"=>"048496124_main_xxl"}
Completed 206 Partial Content in 3ms (ActiveRecord: 0.0ms | Allocations: 279)

预期行为

用户通过/signup页面注册,提交邮箱、密码、确认密码及视频文件;访问/video页面时,视频正常显示并自动播放。

已尝试/确认的操作

  • 使用Video.js,现象一致
  • 重启服务器
  • 确认user.video为ActiveStorage::Attached::One对象
  • 尝试上传不同大小的视频(2GB和1MB)
  • 浏览器开发者工具中确认视频源:
<video autoplay="true" type="video/mp4" src="http://127.0.0.1:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--77812323ea618480d0497c73b1b1cb96856a585a/048496124_main_xxl.mp4</video>

解决方案

1. 修复HTML标签解析问题

从开发者工具的输出可以看到,video标签的src属性未闭合,标签本身也未正确结束,这会导致浏览器解析异常:

<!-- 错误示例 -->
<video autoplay="true" type="video/mp4" src="http://xxx...mp4</video>

修改视频页面的HTML代码,确保标签规范闭合,并添加浏览器自动播放兼容属性:

<video autoplay muted playsinline controls type="video/mp4" src="<%=@redirectURL%>"></video>
  • muted+playsinline:现代浏览器默认限制带声音的视频自动播放,这两个属性可绕过该限制
  • controls:添加播放控件,方便手动测试排查问题

2. 优化ActiveStorage URL生成逻辑

当前使用url_for(@user.video)生成的是重定向URL(/rails/active_storage/blobs/redirect/...),虽然重定向本身合法,但直接使用服务URL可减少跳转环节,避免潜在解析问题。同时修正url_options的格式错误:

class VideoController < ApplicationController
  def index
    # url_options需要传入哈希格式,而非字符串
    ActiveStorage::Current.url_options = { host: "http://127.0.0.1:3000" }
    if session[:user_id]
      @user = User.find(session[:user_id])
      # 直接获取服务URL,同时判断视频是否已上传
      @redirectURL = @user.video.service_url if @user.video.attached?
    end
  end
end

3. 验证视频编码兼容性

部分MP4视频的编码格式可能不被浏览器支持,建议使用H.264视频编码+AAC音频编码的标准MP4文件。可通过FFmpeg重新编码:

ffmpeg -i input.mp4 -vcodec h264 -acodec aac output.mp4

4. 确认ActiveStorage配置正确性

检查config/storage.yml中的本地磁盘服务配置:

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

并在config/environments/development.rb中启用该服务:

config.active_storage.service = :local

测试步骤

  1. 应用上述修改后重启服务器
  2. 重新上传标准编码的MP4视频
  3. 访问/video页面,观察视频播放状态,同时检查控制台是否有新错误提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:17:03