Class: AirVideo::Client
Overview
The AirVideo Client. At this stage it can emulate the iPhone app in all major features.
Minor features, such as requesting a specific streams when using the Live Conversion feature aren’t yet supported, but it’s just a question of figuring out what the server is expecting.
Setting #max_height and #max_width should be working with the Live Conversion, but for some reason it’s not quite happening. Defaults are 640x480
Defined Under Namespace
Classes: FolderObject, VideoObject
Instance Attribute Summary collapse
-
#max_height ⇒ Object
Returns the value of attribute max_height.
-
#max_width ⇒ Object
Returns the value of attribute max_width.
-
#proxy ⇒ Object
readonly
Returns the value of attribute proxy.
Instance Method Summary collapse
-
#cd(dir) ⇒ Object
Changes to the given directory.
-
#conversion_settings(videoobj) ⇒ Object
private.
- #get_details(items) ⇒ Object
-
#get_url(videoobj, liveconvert = false) ⇒ Object
Returns the streaming video URL for the given AirVideo::VideoObject.
-
#initialize(server, port = 45631, password = nil) ⇒ Client
constructor
Specify where your AirVideo Server lives.
- #inspect ⇒ Object
-
#ls(dir = ".") ⇒ Object
Lists the folders and videos in the current directory as an Array of AirVideo::VideoObject and AirVideo::FolderObject objects.
-
#pwd ⇒ Object
(also: #getcwd)
Returns the path to the current directory.
- #request(service, method, params) ⇒ Object
-
#search(re_string, dir = ".") ⇒ Object
Searches the current directory for items matching the given regular expression.
-
#set_proxy(proxy_server_and_port = "") ⇒ Object
Potentially confusing: * Sending ‘server:port’ will use that address as an HTTP proxy * An empty string (or something not recognisable as a URL with http:// put infront of it) will try to use the ENV variable * Sending nil or any object that can’t be parsed to a string will remove the proxy.
Constructor Details
#initialize(server, port = 45631, password = nil) ⇒ Client
Specify where your AirVideo Server lives. If your HTTP_PROXY environment variable is set, it will be honoured.
At the moment I’m expecting ENV to have the form ‘sub.domain.com:8080’, I throw an http:// and bung it into URI.parse for convenience.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/airvideo.rb', line 25 def initialize(server,port = 45631,password=nil) set_proxy # Set to environment proxy settings, if applicable @endpoint = URI.parse "http://#{server}:#{port}/service" @passworddigest = Digest::SHA1.hexdigest("S@17" + password + "@1r").upcase if !password.nil? @req = Net::HTTP::Post.new(@endpoint.path) @req['User-Agent'] = 'AirVideo/2.2.4 CFNetwork/459 Darwin/10.0.0d3' @req['Accept'] = '*/*' @req['Accept-Language'] = 'en-us' @req['Accept-Encoding'] = 'gzip, deflate' @current_dir = "/" @max_width = 640 @max_height = 480 end |
Instance Attribute Details
#max_height ⇒ Object
Returns the value of attribute max_height.
19 20 21 |
# File 'lib/airvideo.rb', line 19 def max_height @max_height end |
#max_width ⇒ Object
Returns the value of attribute max_width.
19 20 21 |
# File 'lib/airvideo.rb', line 19 def max_width @max_width end |
#proxy ⇒ Object (readonly)
Returns the value of attribute proxy.
20 21 22 |
# File 'lib/airvideo.rb', line 20 def proxy @proxy end |
Instance Method Details
#cd(dir) ⇒ Object
85 86 87 88 89 |
# File 'lib/airvideo.rb', line 85 def cd(dir) dir = dir.location if dir.is_a? FolderObject @current_dir = File.(dir,@current_dir) self end |
#conversion_settings(videoobj) ⇒ Object
private
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/airvideo.rb', line 138 def conversion_settings(videoobj) video = videoobj.video_stream scaling = [video['width'] / @max_width, video['height'] / @max_height] if scaling.max > 1.0 video['width'] = (video['width'] / scaling.max).to_i video['height'] = (video['height'] / scaling.max).to_i end # TODO: fill these in correctly AvMap::Hash.new("air.video.ConversionRequest", { "itemId" => videoobj.location[1..-1], "audioStream"=>1,#videoobj.audio_stream['index'], "allowedBitrates"=> AirVideo::AvMap::BitrateList["512", "768", "1536", "1024", "384", "1280", "256"], "audioBoost"=>0.0, "cropRight"=>0, "cropLeft"=>0, "resolutionWidth"=>video['width'], "videoStream"=>0,#video['index'], "cropBottom"=>0, "cropTop"=>0, "quality"=>0.699999988079071, "subtitleInfo"=>nil, "offset"=>0.0, "resolutionHeight"=>video['height'] }) end |
#get_details(items) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/airvideo.rb', line 106 def get_details(items) items = [items] if !items.is_a? Array items.collect! do |item| case item when VideoObject item.location[1..-1] when String item end end.compact! request("browseService","getItemsWithDetail",[items])['result'][0] end |
#get_url(videoobj, liveconvert = false) ⇒ Object
Returns the streaming video URL for the given AirVideo::VideoObject.
92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/airvideo.rb', line 92 def get_url(videoobj,liveconvert = false) raise NoMethodError, "Please pass a VideoObject" if not videoobj.is_a? VideoObject begin if liveconvert request("livePlaybackService","initLivePlayback",[conversion_settings(videoobj)])['result']['contentURL'] else request("playbackService","initPlayback",[videoobj.location[1..-1]])['result']['contentURL'] end rescue NoMethodError raise RuntimeError, "This video does not exist" end end |
#inspect ⇒ Object
133 134 135 |
# File 'lib/airvideo.rb', line 133 def inspect "<AirVideo Connection: #{@endpoint.host}:#{@endpoint.port}>" end |
#ls(dir = ".") ⇒ Object
Lists the folders and videos in the current directory as an Array of AirVideo::VideoObject and AirVideo::FolderObject objects.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/airvideo.rb', line 59 def ls(dir = ".") dir = dir.location if dir.is_a? FolderObject dir = File.(dir,@current_dir)[1..-1] dir = nil if dir == "" begin request("browseService","getItems",[dir])['result']['items'].collect do |hash| case hash.name when "air.video.DiskRootFolder", "air.video.ITunesRootFolder","air.video.Folder" FolderObject.new(self,hash['name'],hash['itemId']) when "air.video.VideoItem","air.video.ITunesVideoItem" VideoObject.new(self,hash['name'],hash['itemId'],hash['detail'] || nil) else raise NotImplementedError, "Unknown: #{hash.name}" end end rescue NoMethodError raise RuntimeError, "This folder does not exist" end end |
#pwd ⇒ Object Also known as: getcwd
Returns the path to the current directory
128 129 130 |
# File 'lib/airvideo.rb', line 128 def pwd @current_dir end |
#request(service, method, params) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/airvideo.rb', line 165 def request(service,method,params) avrequest = { "requestURL" => @endpoint.to_s, "clientVersion" =>221, "serviceName" => service, "methodName" => method, # TODO: Figure out what this is! "clientIdentifier" => "89eae483355719f119d698e8d11e8b356525ecfb", "parameters" =>params } avrequest['passwordDigest'] = @passworddigest if not @passworddigest.nil? @req.body = AvMap::Hash.new("air.connect.Request", avrequest).to_avmap @http.start(@endpoint.host,@endpoint.port) do |http| res = http.request(@req) AvMap.parse StringIO.new(res.body) end end |
#search(re_string, dir = ".") ⇒ Object
Searches the current directory for items matching the given regular expression
121 122 123 124 125 |
# File 'lib/airvideo.rb', line 121 def search(re_string,dir=".") # Get the directory we're searching dir = File.((dir.is_a? FolderObject) ? dir.location : dir,@current_dir) ls(dir).select {|item| item.name =~ %r{#{re_string}}} end |
#set_proxy(proxy_server_and_port = "") ⇒ Object
Potentially confusing:
-
Sending ‘server:port’ will use that address as an HTTP proxy
-
An empty string (or something not recognisable as a URL with http:// put infront of it) will try to use the ENV variable
-
Sending nil or any object that can’t be parsed to a string will remove the proxy
NB. You can access the @proxy URI object externally, but changing it will not automatically call set_proxy
48 49 50 51 52 53 54 55 56 |
# File 'lib/airvideo.rb', line 48 def set_proxy(proxy_server_and_port = "") begin @proxy = URI.parse("http://"+((proxy_server_and_port.empty?) ? ENV['HTTP_PROXY'] : string_proxy)) @http = Net::HTTP::Proxy(@proxy.host, @proxy.port) rescue @proxy = nil @http = Net::HTTP end end |