使用 ruby 下载 youtube 视频以及字幕
来源:互联网 发布:淘宝小号用什么注册 编辑:程序博客网 时间:2024/04/30 14:20
最近喜欢上了 Ruby,非常神奇,所以一直想用它做些什么!
正好女朋友想学些专业英语,就去youtube 上翻了一下,有很多呀,关键还有字幕,
只不过直接在网页上看不是很方便,字幕离视频太远了,看字幕看不到视频,看视频有看不到字幕;
用了代理,虽然看着不卡,但是视频太模糊了,所以决定自己下载他高清版本的视频在电脑上看。
正好拿 Ruby 再练一次手,上次用Ruby 登陆新浪微博用的也挺好的,哈哈
要做的有三步:
1:下载视频,网上搜的大部分已经不适用了,不过youtube 获取 flv 的格式没有大变
2: 下载字幕文件,并转换成 srt 字幕格式
因为刚学 Ruby 很多 Ruby 的高级功能没用,所以基本还是当平常的语言用的,比如每个函数有都要用return 才安心!
呵呵,慢慢学着改吧吧!
里面包含了 cookie.rb 这个事自己原来写新浪微博登录的时候用到的,这里其实也用不到,直接去掉就可以了!
因为众所周知的原因 youtube 在中国是不能直接访问的,所以需要使用socket 代理
类中:
- @ProxyAddress='192.168.0.56'
- @ProxyPort=7777
是定义代理地址的,如果 @ProxyAddress 为 nil 则不适用代理!
另外 socksify 可能需要使用 gem 安装
直接贴代码了:
- require 'net/http'
- require 'uri'
- require 'cgi'
- require 'socksify/http'
- require 'json'
- require 'rexml/document'
- require_relative '../lib/cookie'
- class RstTime
- def initialize(sec)
- @sec = sec.to_f
- end
- def Time
- tsec = @sec.to_i
- #puts tsec.to_s
- ms = @sec - tsec
- ms = (ms * 1000).to_i
- sec = tsec % 60
- tsec /= 60
- minute = tsec % 60
- tsec /= 60
- hour = tsec
- sprintf("%02d:%02d:%02d,%03d",hour,minute,sec,ms)
- end
- end
- class YoutubeVideo
- def initialize page_uri
- @ProxyAddress='192.168.0.56'
- @ProxyPort=7777
- @cookies = Cookie.new()
- @UserAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1'
- @VideoUri = URI.parse page_uri
- @UriPars = CGI.parse(@VideoUri.query)
- if @UriPars.has_key?('v')
- @VideoID = @UriPars['v'].first
- end
- end
- def IsValid
- return @VideoID != nil
- end
- def DownloadFile(url ,saveto)
- uri = URI(url)
- writetotal = 0
- saveto = saveto.gsub('/','-')
- Net::HTTP.SOCKSProxy(@ProxyAddress, @ProxyPort).start(uri.host, uri.port) do |http|
- request = Net::HTTP::Get.new uri.request_uri
- http.request request do |response|
- open saveto, 'w' do |io|
- response.read_body do |chunk|
- writetotal += chunk.length
- io.write chunk
- end
- end
- end
- end
- return writetotal
- #open(saveto, "wb") do |file|
- #file.write(res.body)
- #end
- end
- def DownloadVideos()
- index = 0;
- #puts JSON.pretty_generate(@downloadUrl)
- downloadto = @title.first + ".flv"
- @downloadUrl.each do |x|
- puts "download video:" + downloadto
- break if DownloadFile(x,downloadto) > 0
- end
- end
- def DownloadLyrics()
- return if @lyricUrl == nil
- lyric = @title.first + ".flv.srt"
- res = HttpGet(@lyricUrl+'&type=track&lang=en&name&kind=asr&fmt=1')
- doc = REXML::Document.new(res.body)
- index = 1
- lyric = lyric.gsub('/','-')
- open lyric, 'w' do |io|
- doc.elements.each('transcript/text') do |ele|
- start = ele.attributes['start'].to_f
- starttime = RstTime.new(start)
- endtime = RstTime.new(start + ele.attributes['dur'].to_f)
- io.write index.to_s + "\n"
- io.write starttime.Time + ' --> ' + endtime.Time + "\n"
- io.write ele.text
- io.write "\n"
- io.write "\n"
- index += 1
- end
- end
- end
- def ParseVideoUri()
- return nil if @VideoID == nil
- infoUri = "http://www.youtube.com/get_video_info?video_id=#{@VideoID}&el=detailpage"
- res = HttpGet(infoUri)
- return nil if res.code == 200
- @videoPars = CGI.parse(res.body)
- @url_encoded_fmt_stream_map =CGI.parse(@videoPars['url_encoded_fmt_stream_map'].first)
- @rvs =CGI.parse(@videoPars['rvs'].first)
- #puts @url_encoded_fmt_stream_map
- @videoPars.delete('url_encoded_fmt_stream_map')
- @videoPars.delete('rvs')
- @title = @videoPars['title']
- #puts @url_encoded_fmt_stream_map['url'].class
- @downloadUrl = @url_encoded_fmt_stream_map['url']
- @signs = @url_encoded_fmt_stream_map['sig']
- @downloadUrl.each_index do |x|
- @downloadUrl[x] = @downloadUrl[x] + '&signature=' + @signs[x]
- end
- @lyricUrl = @videoPars['ttsurl'].first
- end
- def HttpGet(url,limit=10,hdrs=nil)
- raise ArgumentError, 'too many HTTP redirects' if limit == 0
- uri = URI(url)
- ck = @cookies.GetDomainCookie(uri.host)
- req = Net::HTTP::Get.new(uri.request_uri)
- req['User-Agent'] = @UserAgent
- if hdrs != nil
- hdrs.each do |key,val|
- req[key] = val
- end
- end
- req['Cookie'] = ck if ck != nil
- if @ProxyAddress != nil
- #puts @ProxyAddress + ':' + @ProxyPort.to_s
- res = Net::HTTP.SOCKSProxy(@ProxyAddress, @ProxyPort).start(uri.host, uri.port) do |http|
- http.request(req)
- end
- else
- res = Net::HTTP.start(uri.host, uri.port) do |http|
- http.request(req)
- end
- end
- @cookies.SaveCookie(uri.host,res.to_hash['set-cookie'])
- if res.kind_of?(Net::HTTPRedirection)
- newurl = res['location']
- newurl = newurl.sub(/^\//,'http://'+uri.host+'/')
- HttpGet(newurl,limit-1)
- end
- return res
- end
- end
- if __FILE__ == $0
- exit if ARGV[0] == nil
- exit if ARGV[0].length == 0
- #yv = YoutubeVideo.new('http://www.youtube.com/watch?v=DC-pQPq0acs&feature=b-vrec');
- #yv = YoutubeVideo.new('http://www.youtube.com/watch?v=dtjrJr1oNmo');
- yv = YoutubeVideo.new(ARGV[0])
- if yv.IsValid() == false
- puts "Invalid url:" + ARGV[0]
- exit
- end
- yv.ParseVideoUri()
- yv.DownloadVideos()
- yv.DownloadLyrics()
- end
0 0
- 使用 ruby 下载 youtube 视频以及字幕
- 使用 ruby 下载 youtube 视频以及字幕
- 下载youtube 视频和字幕
- 如何从youtube上下载视频以及字幕
- Youtube 视频下载,字幕提取方法
- YouTube视频和字幕下载完美方案
- 如何下载 Youtube 视频的字幕?
- 如何下载YouTube视频及字幕
- 使用 Youtube-dl 来下载YouTube视频
- 使用youtube-dl下载YouTube视频
- YouTube字幕下载
- 下载youtube 字幕
- 怎样批量下载YouTube视频专辑,支持匹配字幕?
- 怎样下载YouTube字幕文件
- Macbook 中关于下载器和Youtube视频及字幕下载播放问题
- Youtube上面的Google Python Class视频下载教程,带字幕【亲测成功!】
- Youtube上面的Red5 官方视频下载教程,带字幕【亲测成功】
- 下载youtube的视频
- git 的概括,到现在为止,git的基本的操作我都讲完了
- Qt 2D绘图
- HDU 2647 Reward
- [C++]LeetCode 27: Remove Element(删除数组中指定元素)
- LeetCode的easy题集合(C++实现)三
- 使用 ruby 下载 youtube 视频以及字幕
- HDU 2544 最短路
- Oracle安装过程
- 【转载】两张图解读Java异常与断言
- HDU 1142 A Walk Through the Forest
- 2015年度精品 最新力作32位和64位xp,win7,win8,win10系统下载(电脑城专用版)
- hihoCoder #1032 : 最长回文子串
- Hibernate学习记录2
- SpringMVC 常用配置说明