Ruby on rails 当您';你在使用后台工作人员吗?
我正在制作一个应用程序,使用Streamio FFMPEG将视频从一种格式转换为另一种格式。我想向用户显示进度百分比,但我正在后台任务中进行代码转换(使用sidekiq和redis),因为代码转换可能需要相当长的时间才能完成 我不知道在浏览器中显示进度的理想方式是什么。对于Streamio,它提供了一种显示其进度的方法,如下所示:Ruby on rails 当您';你在使用后台工作人员吗?,ruby-on-rails,ruby-on-rails-5,Ruby On Rails,Ruby On Rails 5,我正在制作一个应用程序,使用Streamio FFMPEG将视频从一种格式转换为另一种格式。我想向用户显示进度百分比,但我正在后台任务中进行代码转换(使用sidekiq和redis),因为代码转换可能需要相当长的时间才能完成 我不知道在浏览器中显示进度的理想方式是什么。对于Streamio,它提供了一种显示其进度的方法,如下所示: movie.transcode("movie.mp4") { |progress| puts progress } # 0.2 ... 0.5 ... 1.0 #
movie.transcode("movie.mp4") { |progress| puts progress } # 0.2 ... 0.5 ... 1.0
# app/workers/convert_tomp4.rb
class ConvertTomp4
include Sidekiq::Worker
include Sidekiq::Status::Worker
sidekiq_options retry: false
def perform(original_file, attachment_id)
destination_file="tmp/#{Digest::MD5.hexdigest(DateTime.now.to_s)}.mp4"
puts "Transcoding #{original_file} into #{destination_file}"
transcoding_options = %w(-f mp4 -vcodec libx264 -preset slow -acodec aac -b:v 2M -b:a 128k -strict -2)
total 100
at 0
movie=FFMPEG::Movie.new(original_file).transcode(destination_file,transcoding_options) { |p| at p*100 }
attachment=Attachment.find(attachment_id)
attachment.tomp4=File.open(destination_file)
attachment.processing=false
attachment.save
end
end
如何将progress
的值保存到以后可以在浏览器中检索到的内容中?我必须将其保存到变量中吗?归档?到数据库?正如我所说,我不知道这方面的最佳做法是什么。将其保存到数据库听起来会产生太多的开销,我不确定哪个变量可以在完成代码转换所需的时间内保存这些信息
为了简单起见,我们可以说,当访问某个页面时,这可以打印在一个简单的
标记中。稍后我将通过Javascript(使用Vue或React)执行更复杂的操作,以在进度发生变化时打印进度,但现在我只想知道如何检索进度
提前谢谢
更新:
在jdno的帮助下,我成功地实现了这一点
首先,sidekiq安装状态。他们提到必须将它添加到sidekiq中间件中,在此之前,我不知道它“存在”。因此,要将其添加到创建此文件的中间件中,请执行以下操作:
# config/initializers/sidekiq.rb
require 'sidekiq'
require 'sidekiq-status'
Sidekiq.configure_client do |config|
# accepts :expiration (optional)
Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes
end
Sidekiq.configure_server do |config|
# accepts :expiration (optional)
Sidekiq::Status.configure_server_middleware config, expiration: 30.minutes
# accepts :expiration (optional)
Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes
end
然后,我用来对文件进行转码的worker如下所示:
movie.transcode("movie.mp4") { |progress| puts progress } # 0.2 ... 0.5 ... 1.0
# app/workers/convert_tomp4.rb
class ConvertTomp4
include Sidekiq::Worker
include Sidekiq::Status::Worker
sidekiq_options retry: false
def perform(original_file, attachment_id)
destination_file="tmp/#{Digest::MD5.hexdigest(DateTime.now.to_s)}.mp4"
puts "Transcoding #{original_file} into #{destination_file}"
transcoding_options = %w(-f mp4 -vcodec libx264 -preset slow -acodec aac -b:v 2M -b:a 128k -strict -2)
total 100
at 0
movie=FFMPEG::Movie.new(original_file).transcode(destination_file,transcoding_options) { |p| at p*100 }
attachment=Attachment.find(attachment_id)
attachment.tomp4=File.open(destination_file)
attachment.processing=false
attachment.save
end
end
Attachment
是我用来保存文件的模型,而tomp4
是将文件信息保存到Carrierwave的字段<代码>处理是我用来知道辅助进程是否处于活动状态的字段,这只是多余的,但我想将其保存到主数据库中
请注意,我正在使用{p|at p*100}
跟踪进度。通常,p
的值在0.0到1.0之间,所以我用它乘以100来知道百分比。变量at
是来自sidekiq状态的内置变量,就像total
一样
最后,要获取视图中或应用程序中任何其他位置的值,我使用:
Sidekiq::Status::at @attachment.jobid
jobid
是在我将任务发送到队列之前分配的。以下是我在Carrierwave上载程序中使用的部分内容:
# app/uploaders/attachment_uploader.rb
def convert_to_mp4(arg1)
if file.path
if file.extension == 'mov'
original = "#{root}/#{self.model.original.url}"
job_id = ConvertTomp4.perform_async(original,self.model.id)
Rails.logger.debug "Job ID: #{job_id}"
self.model.jobid = job_id
self.model.processing = true
self.model.save
Rails.logger.debug "Sending transcoding to the queue. #{original} with ID: #{job_id}"
end
end
end
请原谅这么多调试器行
original
是我用来保存原始文件的字段。到目前为止,我不知道如何保存上载文件的单一版本,因此我制作了第二个上载程序来处理转换后的文件,并将它们保存到我们用于此目的的tomp4
。它将进度存储在Redis中,从而避免扩展数据库操作
您希望如何向客户公开信息取决于您的需要。对我们来说,进度更新非常缓慢,我们只需每隔几秒钟使用Javascript进行一次轮询。我们有一个表示任务的模型,例如FileConversion
,具有file\u path
和size
等属性,然后通过FileConversionController
公开作业的状态
对于我们的用例来说,这是一个非常好的解决方案,只需要您付出很少的努力。我们使用它。它将进度存储在Redis中,从而避免扩展数据库操作
您希望如何向客户公开信息取决于您的需要。对我们来说,进度更新非常缓慢,我们只需每隔几秒钟使用Javascript进行一次轮询。我们有一个表示任务的模型,例如FileConversion
,具有file\u path
和size
等属性,然后通过FileConversionController
公开作业的状态
对于我们的用例来说,这是一个非常好的解决方案,只需要您付出很少的努力。有趣的是,它看起来很有希望。我来看看。我正在检查gem的安装情况,在中间件链中添加一些东西让我有些不知所措。我能看到一个这样的例子吗?有趣的是,它看起来很有希望。我来看看。我正在检查gem的安装情况,在中间件链中添加一些东西让我有些不知所措。我能看到一个这样的例子吗?