其实对python真是一点都不熟,在用Fabric的时候,想修改远程服务器的文件,直接用open -> write 。却发现,修改的只能是本地文件,即使用with cd() : 进入目录,再调用 open ->write,也没用。
后来用了一个比较恶心的办法,适合修改小文件:
Python代码
- def modify(filename, searched, replaced):
- tmpfile = '/tmp/remote_temp.%s.txt' % os.getpid()
- get(filename,tmpfile)
- try:
- lines = open(tmpfile, 'r').readlines()
- flen = len(lines) - 1
- for i in range(flen):
- if searched in lines[i]:
- lines[i] = lines[i].replace(searched, replaced)
- open(tmpfile, 'w').writelines(lines)
- except Exception, e:
- print e
- put(tmpfile,filename);
- os.remove(tmpfile)
代码写的烂,但能用了!这里的get/put是fabric的一些方法。即:先下载下来,修改好后再put上去!
乱七八槽 的一些函数还有这些:
Python代码
- def modify2(filename, searched, replaced):
- tmpfile = '/tmp/remote_temp.%s.txt' % os.getpid()
- get(filename,tmpfile)
- try:
- lines = open(tmpfile, 'r').readlines()
- flen = len(lines) - 1
- for i in range(flen):
- for j in range(len(searched)):
- if searched[j] in lines[i]:
- lines[i] = lines[i].replace(searched[j], replaced[j])
- open(tmpfile, 'w').writelines(lines)
- except Exception, e:
- print e
- put(tmpfile,filename);
- os.remove(tmpfile)
-
- def modifyReg(filename, searched, replaced):
- tmpfile = '/tmp/remote_temp.%s.txt' % os.getpid()
- get(filename,tmpfile)
- try:
- lines = open(tmpfile, 'r').readlines()
- flen = len(lines) - 1
- for i in range(flen):
- lines[i], v = re.subn(searched, replaced, lines[i])
- open(tmpfile, 'w').writelines(lines)
- except Exception, e:
- print e
- put(tmpfile,filename);
- os.remove(tmpfile)
纯记录。实在不知道怎么写好(其实也是不会写)
这两天一直在纠结视频相关。用MP4的话,直接video标签+mp4的话,默认缓冲至少要5M左右 。如果是移动端,5M 花的时间太长了。所以才尝试用m3u8来解决(嗯。ffmpeg直接支持将视频切成ts,同时生成m3u8文件。我这里就不写了。网上例子太多太多了)
以下内容来自:http://blog.sina.com.cn/s/blog_6cf7acdf0102v0xv.html
1. M3U8文件概念
M3U8文件是指UTF-8编码格式的M3U文件。M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。
2. M3U8文件举例
例如使用云图TV点播直播节目时,发送请求:
http://121.199.63.236:7613/m3u8/cckw1/szws.m3u8?from=bab&fun=yes&chk=y&chunk=xax&ppw=yuntutv&auth=yuntutvyuntutvyuntutv&auth=yuntutvyuntutvyuntutv&nwtime=1406515232&sign=033d5483609e6bc87987fc7d2f30a024
返回M3U8文件,文件内容如下:
XML/HTML代码
- #EXTM3U
- #EXT-X-MEDIA-SEQUENCE:140651513
- #EXT-X-TARGETDURATION:10
-
- #EXTINF:8,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651513[140651513].ts
-
- #EXTINF:9,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651514[140651514].ts
-
- #EXTINF:11,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651515[140651515].ts
-
- #EXTINF:10,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651516[140651516].ts
-
- #EXTINF:12,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651517[140651517].ts
-
- #EXTINF:8,
-
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651518[140651518].ts
-
- #EXTINF:12,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651519[140651519].ts
-
- #EXTINF:8,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651520[140651520].ts
-
- #EXTINF:9,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651521[140651521].ts
-
- #EXTINF:13,
- http://vapp1.fw.live.cntv.cn/cache/289_/seg0/index140651522[140651522].ts
然后根据索引的中链接请求下载音视频并进行播放
3. M3U文件标签及属性说明
M3U文件中可以包含多个tag,每个tag的功能和属性如下:
#EXTM3U
每个M3U文件第一行必须是这个tag,请标示作用
#EXT-X-MEDIA-SEQUENCE:140651513
每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1, 一个media URI并不是必须要包含的,如果没有,默认为0
#EXTINF:,
duration 指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效,title是下载资源的url
#EXT-X-TARGETDURATION
指定最大的媒体段时间长(秒)。所以#EXTINF中指定的时间长度必须小于或是等于这个最大值。这个tag在整个PlayList文件中只能出现一 次(在嵌套的情况下,一般有真正ts url的m3u8才会出现该tag)
#EXT-X-KEY
表示怎么对media segments进行解码。其作用范围是下次该tag出现前的所有media URI,属性为NONE 或者 AES-128。NONE表示 URI以及IV(Initialization Vector)属性必须不存在, AES-128(Advanced EncryptionStandard)表示URI必须存在,IV可以不存在。
对于AES-128的情况,keytag和URI属性共同表示了一个key文件,通过URI可以获得这个key,如果没有IV(Initialization Vector),则使用序列号作为IV进行编解码,将序列号的高位赋到16个字节的buffer中,左边补0;如果有IV,则将改值当成16个字节的16进制数。
#EXT-X-PROGRAM-DATE-TIME
将一个绝对时间或是日期和一个媒体段中的第一个sample相关联,只对下一个meida URI有效,格式如#EXT-X-PROGRAM-DATE-TIME:
For example: #EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00
#EXT-X-ALLOW-CACHE
是否允许做cache,这个可以在PlayList文件中任意地方出现,并且最多出现一次,作用效果是所有的媒体段。格式如下:#EXT-X-ALLOW-CACHE:
#EXT-X-PLAYLIST-TYPE
提供关于PlayList的可变性的信息, 这个对整个PlayList文件有效,是可选的,格式如下:#EXT-X-PLAYLIST-TYPE::如果是VOD,则服务器不能改变PlayList 文件;如果是EVENT,则服务器不能改变或是删除PlayList文件中的任何部分,但是可以向该文件中增加新的一行内容。
#EXT-X-ENDLIST
表示PlayList的末尾了,它可以在PlayList中任意位置出现,但是只能出现一个,格式如下:#EXT-X-ENDLIST
#EXT-X-MEDIA
被用来在PlayList中表示相同内容的不用语种/译文的版本,比如可以通过使用3个这种tag表示3中不用语音的音频,或者用2个这个tag表示不同角度的video在PlayLists中。这个标签是独立存在的,属性包含:
URI:如果没有,则表示这个tag描述的可选择版本在主PlayList的EXT-X-STREAM-INF中存在;
TYPE:AUDIO and VIDEO;
GROUP-ID:具有相同ID的MEDIAtag,组成一组样式;
LANGUAGE:确定使用的主要语言
NAME:人类可读的语言的翻译
DEFAULT:YES或是NO,默认是No,如果是YES,则客户端会以这种选项来播放,除非用户自己进行选择。
AUTOSELECT:YES或是NO,默认是No,如果是YES,则客户端会根据当前播放环境来进行选择(用户没有根据自己偏好进行选择的前提下)。
#EXT-X-STREAM-INF
指定一个包含多媒体信息的 media URI 作为PlayList,一般做M3U8的嵌套使用,它只对紧跟后面的URI有效,格式如下:#EXT-X-STREAM-INF:有以下属性:
BANDWIDTH:带宽,必须有。
PROGRAM-ID:该值是一个十进制整数,惟一地标识一个在PlayList文件范围内的特定的描述。一个PlayList 文件中可能包含多个有相同ID的此tag。
CODECS:不是必须的。
RESOLUTION:分辨率。
AUDIO:这个值必须和AUDIO类别的“EXT-X-MEDIA”标签中“GROUP-ID”属性值相匹配。
VIDEO:同上
参考文档:
http://blog.csdn.net/jwzhangjie/article/details/9744027
http://www.xuebuyuan.com/1726264.html
--------EOF--
上述的内容中有几个标签是必须 的
1、#EXTM3U
2、#EXT-X-TARGETDURATION:10,这个好象一定要是整型。否则可能会认不出
3、#EXTINF:8, 这个数字就是下面一行视频对应的时间长度,可以是浮点型
4、#EXT-X-ENDLIST ,如果是直播这个可以不要,否则还是留着吧
本来我是用PHP+Ngx_http_mp4_module来生成的。直接将视频处理成start=? &end =?,然而看起来很美,这些数据可能会破会源文件,导致在实际播放的时候会不正常,直接就卡住,看浏览器的网络管理中会发现,文件读取失败。
所以最终没办法,只有靠ffmpeg进行文件切割。这时候就相对能看得出了。即使你约定按20秒切分,切出来的文件也是不一样的大小的,而且时长还真不能保证都一样是20s,果然 所谓的无损分割是有讲究的。这里就不深究了。
换成m3u8后,配合ngx_http_accesskey_module可以做一些简单的鉴权。防盗链吧。
总算还好。最终还算是搞定了。做个笔记
在yii1的时候,主从数据库的支持没有那么方便,只能写上多个DB的components,然后在AR的getDB中返回相应的db。这样也可以用来对付主从数据库
Yii2则已经解决这个问题,直接在代码中进行处理即可:
PHP代码
- 'db' =>[
- 'class' => 'yii\db\Connection',
-
-
- 'dsn' => 'dsn for master server',
- 'username' => 'master',
- 'password' => '',
- 'charset' => 'utf8',
- 'tablePrefix' => 'php_',
-
-
- 'slaveConfig' => [
- 'username' => 'slave',
- 'password' => '',
- 'charset' => 'utf8',
- 'tablePrefix' => 'php_',
- 'attributes' => [
-
- PDO::ATTR_TIMEOUT => 10,
- ],
-
- ],
- ];
是不是感觉超级方便,而不止是这样,你还可以配置从服务器组:
PHP代码
- 'db'=>[
-
- 'slaves' => [
- ['dsn' => 'dsn for slave server 1'],
- ['dsn' => 'dsn for slave server 2'],
- ['dsn' => 'dsn for slave server 3'],
- ['dsn' => 'dsn for slave server 4'],
- ],
- ]
更值得称赞的是,主服务器也是多个主服务器的配置就是下面这样,其中字符编码集,表前缀等设置参考上面的。
PHP代码
- 'db'=>[
-
- 'masterConfig' => [
- 'username' => 'master',
- 'password' => '',
- 'attributes' => [
-
- PDO::ATTR_TIMEOUT => 10,
- ],
- ],
-
-
- 'masters' => [
- ['dsn' => 'dsn for master server 1'],
- ['dsn' => 'dsn for master server 2'],
- ],
-
- ];
果然 是轻轻松松啊。
当然 如果你想更轻松的使用,这些,其实就是得用YII2的AR。你就用不着改代码了。。
在转这篇文章的时候,我觉得 很懒,所以我几乎没有排版就直接ctrl+c,ctrl+v就过来了
下面是正文,链接来源是:https://mozillazg.com/2013/12/python-fabric-gateway.html
说实话,跳板机给研发的日常工作添加了些许麻烦。 幸好 fabric 提供了穿越跳板机的功能,使跳板机不再影响我们的工作。
Python代码
- $ fab --version
- Fabric 1.8.1
- Paramiko 1.12.0
Python代码
-
- env.gateway = 'lisi@192.168.100.123'
-
-
- env.hosts = ['foo@111.111.111.111',
- 'bar@111.111.111.112',
- 'bar2@122.123.124.139',
- ]
-
- env.passwords = {
- 'lisi@192.168.100.123:22': 'pssword3',
- 'foo@111.111.111.111:22': 'pssword4',
- 'bar@111.111.111.112:22': 'pssword5',
- 'bar2@122.123.124.139:22': 'pssword6',
- }
-
- @task
- @hosts(env.hosts)
- def foobar():
- pass
穿越跳板机的原理是: SSH 隧道技术 。
到这里转载结束。
之所以转这个,就是因为有些机器实在没有公网IP。所以只能从外面的LVS机器进行跳板处理。
如果是纯手工调无非就是打开系统设置,但这样调整起来有点累。头得扭着半天,然后再慢慢对准它。
其实可以在“系统设置-显示器-排列”,可以先将外接显示器调整为主屏幕,然后回到第一个界面里,对它进行显示和方向进行调整。设置完后就OK了。
然后就方便了,只有有一个让人诟病的地方就是。。。即使竖起来了,你要是选择分屏,它还是只能左右 ,不能上下分屏!!!!