Lindsey B
Lindsey B

Reputation: 556

Uploading a video to vimeo via the API in ruby

I've been trying to upload an MP4 video to vimeo via ruby. At first I thought I would try the ruby gem, but looking at it it uses the now deprecated vimeo API. I've been able to upload via a form I made myself, but entirely with code doesn't seem to be working yet.

I have the following code to upload via the streaming API (it's largely based on the vimeo python library):

auth = "Bearer #{ACCESS_TOKEN}"
resp = HTTParty.post "https://api.vimeo.com/me/videos", headers: { "Authorization" => auth, "Accept" => "application/vnd.vimeo.*+json;version=3.2" }, body: { type: "streaming"}

ticket = JSON.parse(resp.body)
target = ticket["upload_link"]
size = File.size("movie.mp4") 
last_byte = 0

File.open("movie.mp4") do |f|
  while last_byte < size do
    resp = HTTParty.put target, headers: { "Authorization" => auth, "Content-Length" => size.to_s, "Content-Range" => "bytes: #{last_byte}-#{size}/#{size}" }, body: { data: a }
    progress_resp = HTTParty.put target, headers: { "Content-Range" => 'bytes */*', "Authorization" => auth }
    last_byte = progress_resp.headers["range"].split("-").last.to_i
    puts last_byte 
  end
end

resp = HTTParty.delete "https://api.vimeo.com#{ticket["complete_uri"]}", headers: { "Authorization" => auth }

for the very last line the resp outputs the following error:

 "{\"error\":\"Your video file is not valid. Either you have uploaded an invalid file format, or your upload is incomplete. Make sure you verify your upload before marking it as complete.\"}" 

and also last_byte outputs: 28518622 after a single run through the loop which is larger than the actual file size (11458105).

Upvotes: 1

Views: 500

Answers (2)

Lindsey B
Lindsey B

Reputation: 556

HTTParty is the wrong tool to use for this. Changing it to work with the normal Net::HTTP lib did the trick.

  File.open("movie.mp4", "rb") do |f|
    uri = URI(target)
    while last_byte < size do
      req = Net::HTTP::Put.new("#{uri.path}?#{uri.query}", initheader = { "Authorization" => auth, "Content-Length" => size.to_s, "Content-Range" => "bytes: #{last_byte}-#{size}/#{size}"} )
      req.body = f.read

      begin
        response = Net::HTTP.new(uri.host, uri.port).start {|http| http.request(req) }
      rescue Errno::EPIPE
        puts "error'd"
      end

      progress_resp = HTTParty.put target, headers: { "Content-Range" => 'bytes */*', "Authorization" => auth}
      last_byte = progress_resp.headers["range"].split("-").last.to_i
      puts last_byte
    end
  end

Upvotes: 1

Alex Antonov
Alex Antonov

Reputation: 15156

Consider the uploading through gem vimeo. It seems Video::Advanced::Upload fit your needs better than HTTParty

Upvotes: 0

Related Questions