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).
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