Module: Pindo::MediaUrlHelper

Defined in:
lib/pindo/module/pgyer/media_url_helper.rb

Class Method Summary collapse

Class Method Details

.append_query_params(url, params) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 78

def append_query_params(url, params)
  base_url, fragment = url.to_s.split('#', 2)
  separator = base_url.include?('?') ? '&' : '?'
  query = params.map { |key, value| "#{key}=#{value}" }.join('&')
  decorated_url = "#{base_url}#{separator}#{query}"
  fragment ? "#{decorated_url}##{fragment}" : decorated_url
end

.decorate_media_url(url, file_path) ⇒ Object

只拼渲染需要的 width/height,与 JPS 网页端写入 fileUrls 的形态保持一致。 视频不拼 x-oss-process=image/snapshot:那是展示预览图时临时加的参数, 写进 fileUrls 会让请求返回一帧截图而不是视频本身



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 22

def decorate_media_url(url, file_path)
  return url if url.to_s.empty? || file_path.to_s.empty?

  params = []

  dimensions = media_dimensions(file_path)
  if dimensions
    width, height = dimensions
    params << ["width", width]
    params << ["height", height]
  end

  return url if params.empty?

  append_query_params(url, params)
end

.decorated_success_urls(upload_result) ⇒ Object



8
9
10
11
12
13
14
15
16
17
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 8

def decorated_success_urls(upload_result)
  upload_results = upload_result["results"]
  if upload_results.is_a?(Array) && upload_results.any?
    return upload_results.select { |item| item["success"] && item["url"] }.map do |item|
      decorate_media_url(item["url"], item["file_path"])
    end
  end

  upload_result["success_urls"] || []
end

.executable_available?(command_name) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
97
98
99
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 94

def executable_available?(command_name)
  ENV.fetch('PATH', '').split(File::PATH_SEPARATOR).any? do |dir|
    path = File.join(dir, command_name)
    File.file?(path) && File.executable?(path)
  end
end

.image_dimensions(file_path) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 46

def image_dimensions(file_path)
  size = FastImage.size(file_path)
  return nil unless size && size.size == 2

  size.map(&:to_i)
rescue => e
  puts "[PINDO_DEBUG] 读取图片尺寸失败 #{file_path}: #{e.message}" if ENV['PINDO_DEBUG']
  nil
end

.image_file?(file_path) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 86

def image_file?(file_path)
  %w[.png .jpg .jpeg .gif .bmp .webp].include?(File.extname(file_path).downcase)
end

.media_dimensions(file_path) ⇒ Object



39
40
41
42
43
44
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 39

def media_dimensions(file_path)
  return image_dimensions(file_path) if image_file?(file_path)
  return video_dimensions(file_path) if video_file?(file_path)

  nil
end

.video_dimensions(file_path) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 56

def video_dimensions(file_path)
  return nil unless executable_available?("ffprobe")

  stdout, _stderr, status = Open3.capture3(
    "ffprobe",
    "-v", "error",
    "-select_streams", "v:0",
    "-show_entries", "stream=width,height",
    "-of", "csv=p=0:s=x",
    file_path
  )
  return nil unless status.success?

  match = stdout.to_s.strip.match(/\A(\d+)x(\d+)\z/)
  return nil unless match

  [match[1].to_i, match[2].to_i]
rescue => e
  puts "[PINDO_DEBUG] 读取视频尺寸失败 #{file_path}: #{e.message}" if ENV['PINDO_DEBUG']
  nil
end

.video_file?(file_path) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/pindo/module/pgyer/media_url_helper.rb', line 90

def video_file?(file_path)
  %w[.mp4 .mov .avi .mkv .webm].include?(File.extname(file_path).downcase)
end