有时候想看电视节目,但播放的时候自己可能在开会在吃饭在厕上等等,经常错过好多电视节目。每个学校都有电视转播的网站,从那里定时下载,到时候观看就啥都不耽误了,关键还能快进哈~开始搞起~

学校的电视直播地址是http://video.ustc.edu.cn/tv.php,比如用vlc看凤凰卫视:

cvlc rtsp://202.38.64.43/tv7

打开wireshark截点包看看:

可以看到用的是RTSP协议,RTSP协议提供几个方法如下:

非常简单,和HTTP协议类似,使用554端口。到这里,我还不知道直播的视频流是什么格式的,于是在截的包里接着找,发现DESCRIBE的响应包非常大,用了4个TCP分段才组成这个PDU,把这个PDU数据包取出来如下(太大了,截取重要部分):

AccRTSP/1.0 200 OKContent-Type: application/sdpVary: AcceptX-Playlist-Gen-Id: 2222430X-Broadcast-Id: 1989898Content-Length: 4756Date: Tue, 15 Oct 2013 03:40:28 GMTCSeq: 3Server: WMServer/9.6.7600.16564Supported: com.microsoft.wm.srvppair, com.microsoft.wm.sswitch, com.microsoft.wm.eosmsg, com.microsoft.wm.fastcache, com.microsoft.wm.packetpairssrc, com.microsoft.wm.startupprofileLast-Modified: Sat, 30 Dec 1899 00:00:00 GMTCache-Control: x-wms-stream-type="broadcast", no-cache, no-user-cache, privatev=0o=- 201310150103460649 201310150103460649 IN IP4 127.0.0.1s=TV Live10c=IN IP4 0.0.0.0b=AS:749a=maxps:8000t=0 0
a=control:rtsp://202.38.64.43/tv7/
a=etag:{19304D1E-37B9-8A6B-A6DB-2B3566BAFA98}
a=range:npt=5.000-5.000
a=type:broadcast
a=recvonly
a=pgmpu:data:application/x-wms-contentdesc,8,language,31,0,,44,WMS_CONTENT_DESCRIPTION_SERVER_BRANDING_INFO,31,12,WMServer/9.6,6,author,31,7,USTCNIC,5,title,31,9,TV%20Live10,51,WMS_CONTENT_DESCRIPTION_PLAYLIST_ENTRY_START_OFFSET,3,4,5000,47,WMS_CONTENT_DESCRIPTION_PLAYLIST_ENTRY_DURATION,3,1,0,58,WMS_CONTENT_DESCRIPTION_COPIED_METADATA_FROM_PLAYLIST_FILE,3,1,1,42,WMS_CONTENT_DESCRIPTION_PLAYLIST_ENTRY_URL,31,1,/%0D%0A
a=pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,MCaydY5mzxGm2QCqAG

从最后一句可以看出,视频流格式就是ASF格式。后面有个base64,然后后面4个tcp包都是这样的字符,我猜是base64转码的头信息,结果证实了我的猜想~把base64后面的字符串解码成二进制文件(用linux自带的base64工具),如下:

这种ASF的视频格式我认为是落后的,所以没必要搞的很明白,能用就好。0x30 0x26就是ASF文件的开始,这个没错,果然是头信息。第二行前8个字节代表视频头的长度,这个地方很重要,我在这儿浪费了好长时间,它的长度不是0x94 0x0a 0x00 ... 0x00,而是翻过来,小端模式来看,和普通的TCP包段有所区别,很坑~所以它的包大小为:0x0a94,即2708字节。通过截取的数据包发现,SETUP发送两次,第一次先请求audio,同时获得sessionID,因为RTSP是有状态的协议,需要一个session来维持;第二次请求video,这时发送的请求包里必须带着sessionID。定义的代码如下:

import socket
import time
import re
values={'ip':'202.38.64.43','port':554,'url':'rtsp://202.38.64.43/tv5','userAgent':'LibVLC/2.0.8 (LIVE555 Streaming Media v2011.12.23)',}def OPTIONS(url,seq,userAgent):msg='OPTIONS '+url+' RTSP/1.0\r\n'msg+='CSeq:'+str(seq)+'\r\n'msg+='User-Agent:'+userAgent+'\r\n'msg+='\r\n'print(msg)msg=msg.encode('utf8')return msgdef DESCRIBE(url,seq,userAgent):msg='DESCRIBE '+url+' RTSP/1.0\r\n'msg+='CSeq:'+str(seq)+'\r\n'msg+='User-Agent:'+userAgent+'\r\n'msg+='Accept:application/sdp\r\n'msg+='\r\n'print(msg)msg=msg.encode('utf8')return msgdef SETUP_audio(url,seq,userAgent):msg='SETUP '+url+'/audio'+' RTSP/1.0\r\n'msg+='CSeq:'+str(seq)+'\r\n'msg+='User-Agent:'+userAgent+'\r\n'msg+='Transport:RTP/AVP;unicast;client_port=40816-40817\r\n'msg+='\r\n'print(msg)msg=msg.encode('utf8')return msgdef SETUP_video(url,seq,userAgent,sessionID):msg='SETUP '+url+'/video'+' RTSP/1.0\r\n'msg+='CSeq:'+str(seq)+'\r\n'msg+='User-Agent:'+userAgent+'\r\n'msg+='Transport:RTP/AVP/TCP;unicast;interleaved=0-1\r\n'msg+='Session:'+sessionID+'\r\n'msg+='\r\n'print(msg)msg=msg.encode('utf8')return msgdef PLAY(url,seq,userAgent,sessionID):msg='PLAY '+url+' RTSP/1.0\r\n'msg+='CSeq:'+str(seq)+'\r\n'msg+='User-Agent:'+userAgent+'\r\n'msg+='Session:'+sessionID+'\r\n'msg+='\r\n'print(msg)msg=msg.encode('utf8')return msg

函数的使用如下所示:

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((values['ip'],values['port']))
seq=1
print('-------------OPTIONS----------------')
s.send(OPTIONS(values['url'],seq,values['userAgent']))
seq+=1
data=s.recv(1024*10)
message=data.decode('utf8')
print(message)
print(len(message))print('-------------DESCRIBE----------------')
s.send(DESCRIBE(values['url'],seq,values['userAgent']))
seq+=1
data=s.recv(1024*10)
length=len(data)
print(length)
message=data.decode('utf8')
while True:data=s.recv(1024*10)tmp=len(data)message+=data.decode('utf8')if tmp<length:break
print(message)
print(len(message))print('-------------SETUP_audio----------------')
s.send(SETUP_audio(values['url'],seq,values['userAgent']))
seq+=1
data=s.recv(1024*10)
message=data.decode('utf8')
print(message)
print(len(message))rule=re.compile('Session:(.*);')
sessionID=rule.findall(message)
if len(sessionID)!=0:sessionID=sessionID[0]print('-------------SETUP_video----------------')
s.send(SETUP_video(values['url'],seq,values['userAgent'],sessionID))
seq+=1
data=s.recv(1024*10)
message=data.decode('utf8')
print(message)
print(len(message))print('-------------PLAY----------------')
s.send(PLAY(values['url'],seq,values['userAgent'],sessionID))
seq+=1
data=s.recv(1024*10)
message=data.decode('utf8')
print(message)
print(len(message))f=open('video.asf','wb')
while True:data=s.recv(1024*10)print(len(data))f.write(data)

这个video.asf文件还是半成品,还需要把DESCRIBE的base64字符串解码成ASF文件头,拼接起来,这个很容易,关键这里面还有一个小问题,因为并不是把视频流直接放到每个TCP包中,而是每个TCP包还有一个可变长的包头,把它们去掉就是完整的视频,但是在我按位找每个位代表的意义的时候,我在bbs上的提问有了回答,感谢linux版主SoRSs的帮助,提供了rtspdump,用这个直接就可以搞起,那此时我的工作就显得毫无意义了哈~用法如下:

php rtspdump.php -r rtsp://202.38.64.43/tv5 -a tcp -o tv.asf

现在的码农大多数都不是从0开始闭门造车,各种代码资源git clone一下如探囊取物,很多自己想的东西都是有大神们之前做过了,何不直接拿来用呢?如果真想研究细致一点可以再细究,如果不想研究,比如我对这个ASF格式就不太喜欢,内心总感觉是注定要淘汰的东西,所以我也只是为了下载视频而做这件事儿,但有现成的程序(虽然是php的),我也就没有再做下去的理由了,花时间在更感兴趣的事情上罢~哈哈,这是我的小感悟,以后一定先搞好调研再搞起!最后,再感谢下linux版主~

转载请注明:转自http://blog.csdn.net/littlethunder/article/details/12875339

把学校直播的电视节目保存到本地相关推荐

  1. 一直播回放视频怎么保存到本地电脑 经验分享

    图是成功提取截图经验,默认保存下来后为mp4格式. 根据以往经验清晰度跟原先一样,本演示截图ps处理了下, 所以人物较为模糊,视频码率平均每分钟8M:不要问清楚不清楚 都是跟原先一样的.+Q57645 ...

  2. 如何做电视节目的视频直播(电视台节目直播)

    [  原创文章  ] STEP1 . 硬件准备及设备连接 场景说明: 1.电视节目直播一般是用于电视信号的直播,对一个电视频道的的信号进行直播,常用于电视台.校园电视节目等: 2.电视信号直播,实现在 ...

  3. android live 电视 源码,GitHub - mxiaoguang/LivePlayback: Android TV直播电视节目 ,包含各央视频道及卫视频道...

    Android TV直播电视节目 更多技术博客,项目,欢迎关注公众号: Android TV开发交流群:135622564 传统电视直播节目,在Android TV上起着越来越重要的作用,央视,各地卫 ...

  4. android电视直播集成,vlc_for_android(基于git-3.0.0)快速集成并播放电视节目直播

    VLC是用的很广泛的多媒体播放器框架,我之前也写过关于<VLC源码及各modules功能介绍>,VLC较其他多媒体播放框架要复杂更多.今天是djstava关于他编译vlc-android源 ...

  5. 在Windows 7 Media Center中无需电视调谐器观看电视节目

    Even if your computer doesn't have a TV tuner card, you can still watch broadcast television program ...

  6. 用计算机录节目,如何在电脑上录制电视节目?高清稳定的录制方法分享

    繁重的工作之余,很多小伙伴都会选择观看以下电脑节目作为娱乐消遣的一部分.而在观看电脑电视节目的过程当中,我们总会有一些将一些精彩片段保存下来的需求,但是苦于视频网站没有权限最终不了了之.那么,如何在电 ...

  7. 电视节目推广方案,综艺节目推广方案怎么写

    电视综艺节目的火爆离不开互联网舆论造势,超过90%的热门电视综艺节目,在上映前后进行了大量的互联网宣传,互联网已经成为影响收视率的重要因素.一档电视综艺节目最终能否成功,怒蛙网络综合比较几个因素大概占 ...

  8. 电视盒子有哪些软件支持电视节目回看?

    现在很多电视节目播出后都支持回看,但是很多人都还不知道怎么操作才能电视节目回看?而且也不知道哪些软件可以支持回看?因为不是所有软件都可以支持回看的.其实支持回看的软件有很多,只是大家平时在用软件的时候 ...

  9. 投影仪怎么看电视节目?超简单几个步骤小白也能马上学会

    小时候我们大院看电视节目都是通过胶卷投影实现的,简单原理就是把图像或者视频投射到大白布上,让更多的人一起来欣赏,这是最开始的投影概念.由于现在科学技术的进步,不同于以前的投影设备,更加智能化的投影仪应 ...

最新文章

  1. Android 多语言
  2. DEDECMS教程:上/下一篇文章标题长度的截取方法
  3. 总分的公式计算机,装机模拟器各配件跑分及计算公式分享 3DMark分数怎么算 3DMark分数计算公式_游侠网...
  4. 《强化学习周刊》第24期:CORL 2021强化学习的最新研究与应用
  5. Lighttpd 配置与性能优化
  6. 项目集成自动分词系统ansj,实现自定义词库
  7. 海思移植opencv+车辆检测
  8. java调用jni接口,Java 中通过jni接口调用native code
  9. 高端ERP软件市场漫谈:崇洋无罪 自重有理
  10. javascript --- 几个其他的跨域技术(图像Ping、JSONP、Comet)
  11. JUnit5 TestSuite替代
  12. 产品运营必备的素质有哪些
  13. qq空间把android改成iphone,qq空间改iPhone6 Plus方法 qq空间改手机型号教程
  14. java thread 简单写法_Java线程池写法改写为C#线程池写法
  15. TensorFlow练习13: 制作一个简单的聊天机器人
  16. “互联网+”环境下高职毕业生求职风险应对策略
  17. Idea自定义注释、作者一键生成详细介绍
  18. 备赛电赛学习硬件篇(七):智能小车底板设计,暂时停更该系列
  19. EXCEL 按字符进行数据截取
  20. Timer 源码解读 (2) TaskQueue 最小堆实现的优先队列

热门文章

  1. java中NaN是什么意思
  2. 恢复 mysql 快照_SQL如何使用快照恢复之前的数据
  3. 记一次Android Studio的Enable VT-x in your BIOS问题解决
  4. 英文翻译葡萄牙语-批量英文转换葡萄牙语-各种语言免费互译转换
  5. note_2017_3.c
  6. TensorFlow的基础概念05
  7. 随机布置地雷java_java 生成0-80之间10个不同的随机数
  8. nodejs 下载必应中国的壁纸
  9. 判定表与判定树的画法_食品生产许可现场审核中怎样识别及判定关键控制点
  10. AngularJS之input指令