.so 封装是什么的库文件直接解压后得到一些命名为0 1 2 ……的文件是什么…

网红当道,越来越多的产品也随波开启了单口相声模式,一向严谨的苹果也不例外。虽然每...
耳机插孔的消失意味着我们的使用习惯不得不改变了。
随着直播服务的运营成本越来越高,商业模式同质化越来越严重,行业面临洗牌只是时间问...
即使 Galaxy Note 7 不出现那样的问题,今年赢的或许还是 iPhone 7 ~
仍然有一些果粉选择等待,他们认为 iPhone 7 系与 6s 相比差异还不是非常之大,正在等...
虽然 Geekbench 跑分信息中包含的设备信息没有其他测试软件那么多,但是型号本身就是...
当然现在关于AirPods的体验报告还较少,待这款产品正式发售后我们才会对它有更全面的...
许多人都认为,iPhone 7 Plus 上首次安装双摄像头标志着这一设计将成为市场的主流。
《大航海之路》是由网易开发的首款3D航海冒险类手游,最早解开神秘面纱还是在今年网易...
虽然说人类在地球上已经生活了上万年,但是人类对于这个星球的认知还是非常肤浅的,即...
在浩瀚无垠的宇宙中人们可以天马行空的放飞自己的想象力,什么故事、剧情都可以在宇宙...
动人的剧情,精良的音效,渐渐浮出水面的谜团,还算比较好看的画面,《淹没》其实可以...
曾经开发过《风雨世界(The Whispered World)》、《德波尼亚(Deponia)》等佳作的游...
近日,著名游戏开发商麒麟狗(Chillingo)在苹果商店当中推出了其休闲新作《眩晕赛车...
文字、图片、链接、声音,我们在日常生活中接触到的信息是如此的多种多样,而要想将这...
不过稍显遗憾的是,并未推出iPhone 7的版本。
或许这将是全球首款内置DAC(数字模拟转换器)和LAM模块(lightning audio module)的...
这款产品能够将 iPhone 7 手机上的 Lightning 接口变成两个,可以在听音乐的同时给手...
有观点认为,苹果此次大举进军无线耳机只不过是为了“勇敢地”开辟一块新的赚钱的沃土...
其实说了这么多话,归根结底还是三个字:买买买!
与耳机孔防尘塞不同的是,设计师希望 iPhone 6s 能完全模拟出 iPhone 7 取消了 3.5mm ...
这些配件有基座、有电池背壳,当然还有手机壳。
苹果已经对设备的防水功能做了详细说明,你可以在苹果说明的范围内任性。
MKV 换封装成MP4,最新版本0.220a,简单方法解决,不需命令行
注册时间 最后登录
在线时间3660 小时 UID
主题帖子人气
金苹果, 积分 1769, 距离下一级还需 1231 积分
记得好久以前曾经发过这么个教程,把mkv换封装成mp4,
今天重新发一个升级版供大家参考一下。
这样做的好处有:
1.mkv的源质量比较高,换封装不处理视频部分,只压音频,因此质量得到最大化保留。
2.视频处理是最花时间的部分,换封装大大减少了处理时间。H.264具有慢工出细活的特性,压高清,给你1:1的转码时间就谢天谢地了。
3.谁不想享受mp4的标准化带来的各种功能?软字幕,章节,海报等等。
4.iPad对mp4的硬件解码支持度比较高,在官方的那个界面播放,可以播放mp4的内嵌软字幕,
还能看到海报和简介,界面效果要比avplayer 好(btw, avplayer 还不是最好的播放器,buzzplayer 最牛,没有之一)
如果你认为换封装还是太费时间,那多半是那种视频下的质量很差,只求avplayer看一遍就过的懒货。
这里提供的教材,是给那些真正喜欢看电影和电视剧,看完之后会收藏得工工整整的正派人士使用的,
懒货、抱怨党、RMVB控请绕道。
首先到这个链接下载:
里面有direct download。
打开软件主界面,把你的mkv往上一拖:
1.jpg (80 KB, 下载次数: 0)
09:51 上传
你的mkv 轨道信息就全显示出来了,见到最下面tag那一栏吗,
那里就是编辑你的mp4显示信息的地方,点旁边那个铅笔图标:
2.jpg (56 KB, 下载次数: 0)
09:51 上传
进去edit tags的界面,下面有个菜单可以选你的媒体类型,
如果是电视剧,就选tv show,有菜鸟问,这个有什么用?
就是让你的mp4导入itunes 之后,直接归类到电视剧那一类里面的,
干净、省事,同样的music video也可以这样处理。
下面的hdvideo一栏打上勾之后就可以打hd标志,
有720p和1080p两种。
接下来的信息,如果你觉得很难填,没问题的,软件会自动为你搜寻信息,
这就是它最厉害的地方,点右边那个search
3.jpg (125 KB, 下载次数: 0)
09:51 上传
立刻就给你搜出来了。点save 会到主界面。
如果你觉得一切都稳妥了,就点主界面下方的start,就会开始处理了。
这个软件换封装转码音频使用的是qaac,也就是quicktime pro内部的aac编码器,
是目前有损压缩的最佳方案。
如果你的mkv有字幕轨的话,软件也会自动显示出来,并且在处理的时候,
把它封装到m4v内部形成一个可开关软字幕。支持srt和ssa字幕,如果是外挂的,
没问题,只要把字幕文件名和mkv的设置成一样,放置在同一个目录下,
软件就会自动检测出来。
这个软件最人性化的地方,就是自动的把720P的level 标记改写成iPad/iPhone 支持的标准,
对于iPad 1 和 Touch 4/iPhone 4/这样的视频性能稍微差一点的设备来说,用处也是蛮大的。
最后,给大家看看我的一个mp4显示效果吧:
IMG_0197.jpg (110 KB, 下载次数: 0)
09:56 上传
和iTunes 商店卖的一模一样的效果。而且,itunes 的版本是发售版往往会经过剪片的,
配乐也往往和首播的不一样,所以大家能下HDTVrip的话还是尽量下,最好别碰web-dl 5.1的版本,
TV版收藏价值是不小的。
<p id="rate_401" onmouseover="showTip(this)" tip="&a
href=&forum.php?mod=redirect&goto=findpost&ptid=5003470&pid=&fromuid=1&&&span &多谢分享!好东西!马克了!&/span&&/a&&人气 + 5
" class="mtn mbn">
<p id="rate_8232" onmouseover="showTip(this)" tip="要得,100m的mkv照卡的路过,还是mp4好!!!&人气 + 1
" class="mtn mbn">
<p id="rate_9109" onmouseover="showTip(this)" tip="感谢分享^_^&人气 + 1
" class="mtn mbn">
<p id="rate_39" onmouseover="showTip(this)" tip="威锋有你更精彩:)&人气 + 1
" class="mtn mbn">
<p id="rate_660" onmouseover="showTip(this)" tip="感谢分享^_^&人气 + 7
" class="mtn mbn">
<p id="rate_60" onmouseover="showTip(this)" tip="很实用,学习了&人气 + 1
" class="mtn mbn">
<p id="rate_7926" onmouseover="showTip(this)" tip="满上&人气 + 7
" class="mtn mbn">
<p id="rate_9142" onmouseover="showTip(this)" tip="感谢分享^_^&人气 + 1
" class="mtn mbn">
<p id="rate_2372" onmouseover="showTip(this)" tip="威锋有你更精彩:)&人气 + 7
" class="mtn mbn">
<p id="rate_1423" onmouseover="showTip(this)" tip="威锋有你更精彩:)&&加满!&人气 + 3
" class="mtn mbn">
<p id="rate_0911" onmouseover="showTip(this)" tip="感谢分享^_^&人气 + 1
" class="mtn mbn">
<p id="rate_5051" onmouseover="showTip(this)" tip="我也在论坛下载过一个MKV2MP4.有机会下载楼主的看看&人气 + 1
" class="mtn mbn">
<p id="rate_4750" onmouseover="showTip(this)" tip="很好的东西,我一直也喜欢下载MKV的高清MV之类的,之前都是用QQ播放器转换的M&人气 + 1
" class="mtn mbn">
<p id="rate_87" onmouseover="showTip(this)" tip="我只能说很强大,很强大&人气 + 3
" class="mtn mbn">
<p id="rate_4081" onmouseover="showTip(this)" tip="威锋有你更给力:)&人气 + 3
" class="mtn mbn">
<p id="rate_933" onmouseover="showTip(this)" tip="感谢分享^_^&人气 + 1
" class="mtn mbn">
评分次数47
要得,100m的mkv照卡的路过,还是mp4好!!!
感谢分享^_^
威锋有你更精彩:)
感谢分享^_^
很实用,学习了
感谢分享^_^
威锋有你更精彩:)
威锋有你更精彩:)&&加满!
感谢分享^_^
我也在论坛下载过一个MKV2MP4.有机会下载楼主的看看
很好的东西,我一直也喜欢下载MKV的高清MV之类的,之前都是用QQ播放器转换的M
我只能说很强大,很强大
威锋有你更给力:)
感谢分享^_^
感谢分享^_^
无法播放是什么个情况?
助人为乐^_^
技术贴必须收藏
威锋有你更精彩:)
期待尽快修复下载。
精品文章^_^
支持,有空试试!
用Mac的纯支持了
威锋有你更精彩:)
威锋有你更精彩:)
顶你个肺啊我
威锋有你更给力:)
感谢分享^_^
谢谢分享!!!!
本人级别不够高,只能加两分了。谢谢
感谢分享^_^
我也在追teenwolf&&来楼主 握个手
请问支持hi10p 10bit吗?
威锋有你更给力:)
楼主忘了视频的前提条件,如果只用一个mkv带过的话,是很不负责的。
神贴!必须收藏!
感谢分享。
不错。。曾经用过这软件。灰常不错
顶起,营养贴,这个必须支持!
很好,一直在找能封个像模像样的MP4文件。
威锋有你更精彩:)
本人技术贴皆是原创,请切勿转载!
注册时间 最后登录
在线时间1181 小时 UID
主题帖子人气
这个绝对要顶起了!!~~
注册时间 最后登录
在线时间1787 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间4064 小时 UID
主题帖子人气
怎么添加字幕呢?
注册时间 最后登录
在线时间3275 小时 UID
主题帖子人气
对lukeH于 19:49在楼主发表的主题评分:人气:+5;
记得好久以前曾经发过这么个教程,把mkv换封装成mp4,
今天重新发一个升级版供大家参考一下。
这样做的好处有:
1.mkv的源质量比较高,换封装不处理视频部分,只压音频,因此质量得到最大化保留。
.......威锋有你更精彩:)
注册时间 最后登录
在线时间1365 小时 UID
主题帖子人气
留个名,好帖子
注册时间 最后登录
在线时间446 小时 UID
主题帖子人气
a new hope
对lukeH于 18:51在楼主发表的主题评分:人气:+1;
记得好久以前曾经发过这么个教程,把mkv换封装成mp4,
今天重新发一个升级版供大家参考一下。
这样做的好处有:
1.mkv的源质量比较高,换封装不处理视频部分,只压音频,因此质量得到最大化保留。
.......很好,一直在找能封个像模像样的MP4文件。
注册时间 最后登录
在线时间839 小时 UID
主题帖子人气
注册时间 最后登录
在线时间3748 小时 UID
主题帖子人气
注册时间 最后登录
在线时间446 小时 UID
主题帖子人气
a new hope
另外问下楼主,封出来的MP4文件,ipad播放的时候字幕会带一层半透明的灰色底是怎么回事?
威锋旗下产品
Hi~我是威威!
沪公网安备 29号 | 沪ICP备号-1
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!时间: September 4, 2016
1. 主键+业务虚拟键分表这种方式适合查询比较单一的业务,最大的缺点就是业务对分库分表这层是有感知:查询返回的时候需要在接口层拼接业务的真实Id根据真实业务Id查询,或者更新数据的时候,需要拆分真实业务Id,路由到数据所在表,再根据数据库Id查询虚拟场景假设我们分了1024张表,具体表结构如下:插入流程1. 插入数据,必须带有userId
2. 根据userId计算出xId
xId = userId % 10000;
3. 根据xId定位数据所在表
tNum = xId % 1024; // 最简单的取模hash(具体策略由中间件决定)
4. 插入数据,返回realId
realId = id + xId;单条查询流程1. 根据realId查询, 获取单张表中的Id值
id = realId / 10000; // 整除
2. 获取虚拟键xId
xId = realId % 10000;
3. 根据xId定位数据所在表
tNum = xId % 1024; // 最简单的取模hash(具体策略由中间件决定)
4. 根据表和Id获取单条数据批量查询流程基本和单条查询一致,可优化的点:第3步,根据xId进行分组,将查询同一张表的query放在一次sql的查询语句中2. 主键/业务外键分表这种策略对业务代码可以无侵略性, 为避免Id冲突, 使用外部Id生成器, 以下步骤全在中间件中执行:(根据业务外键的处理同理,查询比较复杂的情况一般都是使用冗余表)虚拟场景假设我们分了1024张表,具体表结构如下:插入流程1. 从Id生成器获取Id
2. 根据Id进行hash (简单的可以使用取模), 获取数据应该插入的表名
tNum = id % 1024;
3. 插入数据表单条查询流程1. 根据Id进行hash (简单的可以使用取模), 获取数据所在表名
tNum = id % 1024;
2. 查询数据批量查询流程基本和单条查询一致,可优化的点:第1步,根据Id进行hash后进行分组,将查询同一张表的query放在一次sql的查询语句中数据的聚合在批量查询的时候,需要 order by group by distinct 的时候,需要在查询出各分表数据之后,在中间件组件中自行实现对数据的处理
时间: August 14, 2016
页面内容的拆分静态内容非状态相关的动态内容状态相关的动态内容HInclude CSI用于pc或者h5页面&hx:include src=&/_fragment?path=&&&/hx:include&Varnish ESI多用于app api的接口返回vcl 4.0;
backend server1 {
.host = &10.162.110.168&;
.port = &80&;
acl local {
&localhost&;
sub vcl_init {
new director = directors.round_robin();
director.add_backend(server1);
sub vcl_recv {
set req.backend_hint = director.backend();
if (req.method == &PURGE&) {
if (client.ip ~ local) {
return (purge);
return (synth(405));
if (req.http.Accept == &text/event-stream&) {
return (pipe);
if (req.http.upgrade ~ &(?i)websocket&) {
return (pipe);
if (req.method != &GET& && req.method != &HEAD&) {
return (pass);
set req.http.Surrogate-Capability = &abc=ESI/1.0&;
if (req.http.X-Forward-For) {
set req.http.X-Forward-For = req.http.X-Forward-For + &,& + client.
set req.http.X-Forward-For = client.
return (hash);
sub vcl_backend_response {
if (beresp.http.Surrogate-Control ~ &ESI/1.0&) {
unset beresp.http.Surrogate-C
set beresp.do_esi =
if (bereq.uncacheable) {
return (deliver);
set beresp.grace = 30s;
# 302 5xx no cache
if (beresp.status == 302 || beresp.status &= 500) {
set beresp.uncacheable =
set beresp.ttl = 120s;
return (deliver);
if (beresp.status == 301 || (beresp.status &= 400 && beresp.status & 500)) {
set beresp.ttl = 120s;
set beresp.ttl = 2400s;
unset beresp.http.Set-C
return (deliver);
sub vcl_pipe {
if (req.http.upgrade) {
set bereq.http.upgrade = req.http.
return (pipe);
sub vcl_deliver {
set resp.http.X-Age = resp.http.A
unset resp.http.A
unset resp.http.V
unset resp.http.X-Powered-By;
unset resp.http.X-V
if (obj.hits & 0) {
set resp.http.X-Cache=&HIT from & + server.
set resp.http.X-Cache=&MISS&;
return (deliver);
workflowvarnish 接收到请求后,增加 Surrogate-Capability:abc=ESI/1.0 头,打到后端后端判断Surrogate-Capability决定是否要使用esi标签来返回 (即判断这个请求是不是从varnish过来的)返回内容时判断是否含有 &esi:include,增加 Surrogate-Control:content=&ESI/1.0& 头varnish 判断 Surrogate-Control 头,决定是否要启用 esi 替换后端应用中的处理生成路由url /_fragment?path=&hx:include src=&/_fragment?path=&&&/hx:include&&esi:include src=&/_fragment?path=&&&/esi:include&注册处理 /_fragment 路由
时间: August 2, 2016
wrk是一款现代化的http压测工具,提供lua脚本的功能可以满足每个请求或部分请求的差异化。wrk中执行http请求的时候,调用lua分为3个阶段,setup,running,done,每个wrk线程中都有独立的脚本环境。wrk的全局属性wrk = {
= &localhost&,
headers = {},
= &userdata&,
}wrk的全局方法-- 生成整个request的string,例如:返回
-- GET / HTTP/1.1
-- Host: tool.lu
function wrk.format(method, path, headers, body)
-- 获取域名的IP和端口,返回table,例如:返回 `{127.0.0.1:80}`
function wrk.lookup(host, service)
-- 判断addr是否能连接,例如:`127.0.0.1:80`,返回 true 或 false
function wrk.connect(addr)Setup阶段setup是在线程创建之后,启动之前。function setup(thread)
-- thread提供了1个属性,3个方法
-- thread.addr 设置请求需要打到的ip
-- thread:get(name) 获取线程全局变量
-- thread:set(name, value) 设置线程全局变量
-- thread:stop() 终止线程Running阶段function init(args)
-- 每个线程仅调用1次,args 用于获取命令行中传入的参数, 例如 --env=pre
function delay()
-- 每个线程调用多次,发送下一个请求之前的延迟, 单位为ms
function request()
-- 每个线程调用多次,返回http请求
function response(status, headers, body)
-- 每个线程调用多次,返回http响应Done阶段可以用于自定义结果报表,整个过程中只执行一次function done(summary, latency, requests)
latency.min
-- minimum value seen
latency.max
-- maximum value seen
latency.mean
-- average value seen
latency.stdev
-- standard deviation
latency:percentile(99.0) -- 99th percentile value
latency(i)
-- raw value and count
summary = {
duration = N,
-- run duration in microseconds
requests = N,
-- total completed requests
-- total bytes received
connect = N, -- total socket connection errors
= N, -- total socket read errors
= N, -- total socket write errors
= N, -- total HTTP status codes & 399
timeout = N
-- total request timeouts
}例子表单的提交wrk.method = &POST&
wrk.body = && -- 直接写死,如果不需要请求数据的差异化
wrk.headers[&Content-Type&] = &application/x-www-form-urlencoded&
-- 如果要实现每次都不一样的表单内容
local queries = {
&language=php&,
&language=java&,
&language=lua&
local i = 0
request = function()
local body = wrk.format(nil, nil, nil, queries[i % #queries + 1])
return body
时间: July 3, 2016
背景在前端开发切图的时候,很多时候示例图片都是不需要的,只需要一个尺寸的图片,还方便后端清晰的知道要输出的图片尺寸。对于访问时候的优化,有2个方案:使用cdn回源 (对于对外开放的服务,自然会在cdn上留下大量一次性的图片)在服务器的内存中生成图片返回 (由于只是提供开发者使用,只要对http缓存做好优化,压力不会很大)大家都知道对于静态图片,nginx对于缓存这些东西都给我们做好了,只需要1~2行的配置就可以搞定;但是注意了,我们这里是在程序中动态生成图片,所以我们需要关心http中浏览器的缓存头EtagExpires:
Cache-Control: max-age=3600
Last-Modified:
If-Modified-Since:
If-None-Match:Cache-Control这里我采用的是对 text, fg, bg, width, height 进行md5处理,因为这几个值就可以确定唯一的图片$md5 = md5(json_encode(compact('width', 'height', 'text', 'bg', 'fg')));
$etags = Input::getEtags();
if (isset($etags[0])) {
$etag = str_replace('&', '', $etags[0]);
if ($etag === $md5) {
App::abort(304, '', ['Content-Type' =& 'image/png', 'Cache-Control' =& 'public, max-age=', 'ETag' =& $md5]);
}YUV 图片文字颜色的获取 (颜色明亮度)更多的使用的时候,往往我们只需要指定背景色,不关心文字的颜色(能看清就行);于是在不同的背景色下面,我们都需要让文字颜色和背景色保持一定的对比度,好了直接看代码吧$greyLevel = $r * .229 + $g * .587 + $b * .114;
if ($greyLevel &= 189) { // 192
$fg = '#666666';
$fg = '#ECF0F1';
}字体选择的优化全英文的情况下 Georgia 的展现效果比较不错,但是包含中文之后效果就大打折扣,所以这里有个小兼容$fontFamily = 'Georgia.ttf';
// 如果包含中文
if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $text)) $fontFamily = 'yahei_mono.ttf';安全控制由于图片的生成会消耗一定的内存,而且图片尺寸越大,耗的内存越多,所以这里对生成图片的尺寸做了1个限制,就是高宽都必须小于等于 2048,否则返回 404
时间: July 3, 2016
背景由于很多时候,视频资源下载很慢,需要用自己的电脑挂机;又或是国外的资源被墙,无法观看;所以需要一个可以挂机下载的服务器。离线下载这步做到之后,又由于download到自己电脑上还需要一段时间,而且有些资源可能是不需要的, 所以又有了在线观看的需求。使用到的软件/框架ScrapyMySQLAria2FfmpegNginxLaravelVideojs流程图下载流程展示流程痛点其实正常的开发流程一般遵照网上的教程或者官方文档就可以很容易的解决;这边讲讲一些需要费一些精力才能解决的问题被js加密过的下载地址一般都是使用eval来执行加密过的字符串,只要先将eval里面的参数给解密出来,然后使用正则匹配解密之后的字符串里面的下载地址就可以了p = re.compile(ur'eval\((.*)')
m = p.search(response.body)
print('---- not match ----')
jsctx = PyV8.JSContext(PyV8.JSClass())
jsctx.enter()
jsctx.eval(r&var a = new String(& + m.group(1))
print(jsctx.locals.a)
content = jsctx.locals.a
p1 = re.compile('(http://[^&]+)')
m1 = p1.search(content)
if not m1:
print('---- cannot find url in js content ----')
videoUrl = m1.group(1)python和aria2的交互# encoding: utf-8
import xmlrpclib
class Pipeline(object):
def __init__(self):
self.s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
def init_hook(self):
self.s.aria2.onDownloadStart(self.onDownloadStart)
self.s.aria2.onDownloadError(self.onDownloadError)
self.s.aria2.onDownloadComplete(self.onDownloadComplete)
def onDownloadStart(self, event):
def onDownloadError(self, event):
def onDownloadComplete(self, event):
def process_item(self, item, spider):
gid = self.s.aria2.addUri([item['video_url']], {&out&: path})
# ...ffmpeg将mp4拆分为HLS命令如下,注意替换&&之间的内容ffmpeg -i &ccc.mp4& -vf scale=-2:360 -profile:v baseline -level 3.0 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls &ccc.m3u8&ffmpeg截取部分视频为gif注意替换命令中的两个变量ffmpeg -ss 00:00:10 -t 5 -i &$filename& -vf scale=360:-1 -b 2048k &$dirname&.gifvideojs播放HLS默认情况之下videojs是不支持播放HLS的,需要引入 videojs-contrib-hls.min.jsvideojs.options.flash.swf = &/js/video-js/video-js.swf&;
videojs('main_video').ready(function() {
this.hotkeys({
volumeStep: 0.1,
seekStep: 5,
enableMute: true,
enableFullscreen: true,
enableNumbers: true
时间: July 3, 2016
更详细的内容可以查看文章结尾的PDF媒体文件处理magic bytes 校验扩展名校验文件名校验mime校验速率限制图片的处理(水印颜色的优化) 颜色深浅的判断图片中心的判断颜色色差的聚类音频的处理视频的处理http api跨域iframe同源策略,document.domain = tool.lujsonp这种跨域实际上是在页面中动态插入一个 &script& 标签,然后在被加载的脚本中执行当前网页里的函数;显而易见,只支持GET请求。ajax2 - Cross-Origin Resource Sharing简单请求预检请求http返回头Access-Control-Allow-Origin: &origin& | *
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
Access-Control-Max-Age: &delta-seconds&
Access-Control-Allow-Credentials: true | false
Access-Control-Allow-Methods: &method&[, &method&]*
Access-Control-Allow-Headers: &field-name&[, &field-name&]*static const auto maxPreflightCacheTimeout = std::chrono::seconds(600);
http请求头Origin: &origin&
Access-Control-Request-Method: &method&
Access-Control-Request-Headers: &field-name&[, &field-name&]*默认情况下 跨域XHR 是不会带上Cookie的,需要设置 withCredentials =附件:
时间: July 3, 2016
使用composer管理composer require phpoffice/phpexcel&?php
error_reporting(E_ALL);
date_default_timezone_set('Asia/Shanghai');
require __dir__ . '/../vendor/autoload.php';
// ... 注意自己赋值$file
$excel = PHPExcel_IOFactory::load($file);
$sheetCount = $excel-&getSheetCount();
echo &sheet count:$sheetCount& . PHP_EOL;
foreach ($excel-&getWorksheetIterator() as $sheet) {
if ($sheet-&getSheetState() === 'hidden') {
$sheetName = $sheet-&getTitle();
echo &sheet name: $sheetName& . PHP_EOL;
$highestColumn = $sheet-&getHighestColumn();
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
$highestRow = $sheet-&getHighestRow();
for ($row = 1; $row &= $highestR $row++) {
$columns = [];
for($col = 0; $col & $highestColumnI $col++) {
$cell = $sheet-&getCellByColumnAndRow($col, $row);
$val = $cell-&getValue();
if ($val instanceof PHPExcel_RichText) {
$columns[] = trim($val-&getPlainText());
$columns[] = trim($val);
var_dump($columns);
}过滤隐藏的worksheetif ($sheet-&getSheetState() === 'hidden')过滤隐藏的行由Excel中auto filter隐藏的行if ($sheet-&getRowDimension($row)-&getVisible())获取单元格颜色获取文字颜色$cell-&getStyle()-&getFont()-&getColor()-&getRGB();获取填充颜色$cell-&getStyle()-&getFill()-&getStartColor()-&getRGB();颜色的差异值是这样,运营那边对不同类型的数据进行了颜色的分类,但是是多个人整理的,所以紫色和淡紫色的运营那边认为是同一个东西;但是程序里面是没法判断,因为紫色的区域太大了;所以这边就需要用到颜色的差异值比对了。| YUV |
|-----|-------------|-------|
| 明亮度 |
| Chrominance |
|Y'UV 的发明是由于彩色电视与黑白电视的过渡时期。黑白视讯只有 Y(Luma,Luminance)视讯,也就是灰阶值。到了彩色电视规格的制定,是以 YUV/YIQ 的格式来处理彩色电视图像,把 UV 视作表示彩度的 C(Chrominance或Chroma),如果忽略 C 讯号,那么剩下的 Y(Luma)讯号就跟之前的黑白电视讯号相同,这样一来便解决彩色电视机与黑白电视机的相容问题。|
|-------|------|-------|
| Luma | 明亮度 |
|RGB -& XYZ -& Lab -& delta E| RGB |
|-----|-------|-----|
| Green | 绿色 |
| 蓝色 |php默认函数 imagecolorclosest // RGB几何距离,由于RGB空间不是颜色感知连续的,所以效果没有Lab'的好这边有个实现好的颜色空间转换的代码
时间: June 1, 2016
pjax = pushState + ajax由于这是一个比较通用的组件,所以我把它写成了slim的Middleware (如果不知道middleware是什么或者怎么写,可以)大概原理是在slim框架渲染之后,输出之前,对dom结构进行分析,摘取出pjax所需要的部分,然后将这部分的内容作为response返回给浏览器的ajax请求预览:
点击分页可以看到效果$app-&add(new \Support\PjaxMiddleware());&?php
namespace S
use Slim\M
use Slim\Http\R
use Slim\Http\R
use Symfony\Component\DomCrawler\C
class PjaxMiddleware extends Middleware
public function call()
$request = $this-&app-&request();
$response = $this-&app-&response();
$this-&next-&call();
if (!$request-&headers('X-PJAX') || $response-&isRedirect()) {
$this-&filterResponse($response, $request-&headers('X-PJAX-CONTAINER'))-&setUriHeader($response, $request);
private function filterResponse(Response $response, $container)
$crawler = new Crawler($response-&getBody());
$response-&setBody($this-&makeTitle($crawler) . $this-&fetchContents($crawler, $container));
private function makeTitle(Crawler $crawler)
$title = $crawler-&filter('head & title')-&html();
return &&title&{$title}&/title&&;
private function fetchContents(Crawler $crawler, $container)
$content = $crawler-&filter($container);
if (!$content-&count()) {
$this-&app-&stop();
return $content-&html();
private function setUriHeader(Response $response, Request $request)
$query = $request-&get();
unset($query['_pjax']);
$response-&header('X-PJAX-URL', $request-&getResourceUri() . '?' . http_build_query($query));
时间: May 31, 2016
由于实际开发中需要查看接口返回值结构和实际的数据样例,每次都写controller再访问url看下是比较麻烦的。所以如果能像 php -a 这样交互的方式调用网站应用中定义的model和function的话,将会极其的方便。目录结构如下:app/
tinkerapp为网站具体逻辑实现的部分public下面有1个index.php为网站的入口tinker就是我们需要接入pysh,实现REPL的文件了由于Slim里面需要PATH_INFO的值,但是命令行运行的时候,这个值是不存在的,所以需要在代码中mock一下;代码如下:#!/usr/bin/env php
require __DIR__ . '/vendor/autoload.php';
$app = require __DIR__ . '/app/bootstrap.php';
$app-&environment = \Slim\Environment::mock([
'PATH_INFO' =& '/playground'
$app-&notFound(function () use ($app) {
$path = $app-&environment['PATH_INFO'];
echo &Cannot route to $path& . PHP_EOL;
$app-&stop();
$app-&error(function (\Exception $e) use ($app) {
echo $e . PHP_EOL;
$app-&stop();
$app-&any('/playground', function () {
$config = new \Psy\Configuration([
'tabCompletion' =& true,
'tabCompletionMatchers' =& [
new \Psy\TabCompletion\Matcher\ClassNamesMatcher,
new \Psy\TabCompletion\Matcher\ClassMethodsMatcher,
new \Psy\TabCompletion\Matcher\ClassAttributesMatcher,
new \Psy\TabCompletion\Matcher\FunctionsMatcher,
$shell = new \Psy\Shell();
$shell-&run();
$app-&run();
时间: April 16, 2016
预览实现基础表的设计前端的实现由于每个回复的展示都需要完整的引用路径,我们需要一个字段来记录本条回复所回复的回复 quote_id,在一个列表中如果每次都递归获取引用的评论,性能上会有很大的瓶颈,所以我们冗余一个字段,记录本条回复的引用路径 quote_pathCREATE TABLE `pre_comments` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`article_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`quote_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`quote_path` varchar(255) NOT NULL DEFAULT '' COMMENT '记录最近的20个值',
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`username` char(15) NOT NULL DEFAULT '',
`content` varchar(1024) NOT NULL,
`up` bigint(20) NOT NULL DEFAULT '0',
`down` bigint(20) NOT NULL DEFAULT '0',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`deleted_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_article_id` (`article_id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;数据展示流程:获取最新的10条评论获取与最新的10条评论相关被引用的评论,最大层级不超过20,超过20的使用查看更多跳转到单独的评论页面组装数据,返回jsonReactjs渲染数据用伪代码可以表示为如下结构&CommentBox&
&CommentList&
&CommentItem&
&CommentQuote&
&CommentQuote&
&CommentToolBar&
&CommentForm&&/CommentForm&
&/CommentToolBar&
&/CommentQuote&
&CommentToolBar&
&CommentForm&&/CommentForm&
&/CommentToolBar&
&/CommentQuote&
&CommentToolBar&
&CommentForm&&/CommentForm&
&/CommentToolBar&
&/CommentItem&
&/CommentList&
&CommentForm&&/CommentForm&
&/CommentBox&优化分库分表通用计数组件缓存静态化通过查询场景来决定分库分表的策略根据articleId查询最新的评论根据articleId 和 commentId更新计数根据articleId 和 quoteId写入新的评论展示某个用户(userId)所有的评论其中有两个分表的路由key articleId 和 userId未完待续
时间: March 5, 2016
反编译查看源码cd ~/Library/Application Support/IntelliJIdea15/mybatis_plus/lib/使用 JD-GUI 打开 mybatis_plus.jar,查看源码:修改验证逻辑使用javassist修改字节码import javassist.*;
class MyCrack {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass c = pool.get(&com.seventh7.mybatis.util.JavaUtils&);
CtMethod m = c.getDeclaredMethod(&refValid&);
m.setBody(&{ validated = valid = }&);
c.writeFile();
CtClass cc = pool.get(&com.seventh7.mybatis.service.JavaService&);
CtMethod mm = cc.getDeclaredMethod(&stop&);
mm.setBody(&{ }&);
cc.writeFile();
javac -classpath &.:javassist.jar:mybatis_plus.jar& MyCrack.java
java -classpath &.:javassist.jar:mybatis_plus.jar& MyCrack此时会在当前目录下生成修改过的两个类文件,使用压缩软件替换jar包中的这两个文件;重启idea。com/seventh7/mybatis/service/JavaService.class
com/seventh7/mybatis/util/JavaUtils.class
时间: February 19, 2016
背景在系统改造的时候,从php迁移到java;由于php中为了节省redis的内存,对缓存的数据做了 gzcompress 处理;为了能读取出数据,有两套方案:刷数据,将redis中老的数据清理掉,去掉 gzcompress 的步骤(缺点:刷数据的时间,和读取代码上线的时间点无法吻合;数据的写入入口比较多,容易遗漏)java中读取的时候可以进行 gzuncompress一些知识知道这些知识候就能避免我在实现过程中遇到的很多问题。PHP中的 gzcompressThis function compresses the given string using the ZLIB data format.Note:This is not the same as gzip compression, which includes some header data. See gzencode() for gzip compression.一直以为 gzcompress 就是 gz 的压缩,php中使用的 zlib 来压缩,压缩完的结果中携带了头信息,直接使用 gz 解压是不认这种格式的。JAVA中的 new String(byte[])java.lang.StringCoding.StringDecoder 当在编码 byte[] 不能处理的时候会进行一些处理;所以说 (new String(compressedByte)).getBytes() 和 compressedByte 并不一定会完全一样。说到这里就可以看下 jedis 提供的接口了,刚开始我是使用的 String get(String key),于是由于上面的原因,当我用这个返回值 getBytes() 的时候就已经发生了变化。正确的使用方法应该是使用 byte[] get(byte[] key),由于比较繁琐,封装一下。实现
public static String get(Jedis jedis, String key) {
byte[] byteKey = key.getBytes();
byte[] element = jedis.get(byteKey);
return new String(gzuncompress(element));
public static List&String& mget(Jedis jedis, List&String& keys) {
byte[][] byteKeys = new byte[keys.size()][];
for (int i = 0; i & keys.size(); i++) {
byteKeys[i] = keys.get(i).getBytes();
List&byte[]& elements = jedis.mget(byteKeys);
List&String& result = new ArrayList&&();
for (byte[] element : elements) {
result.add(new String(gzuncompress(element)));
public static byte[] gzuncompress(byte[] data) {
byte[] unCompressed =
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
Inflater deCompressor = new Inflater();
deCompressor.setInput(data);
final byte[] buf = new byte[1024];
while (!deCompressor.finished()) {
int count = deCompressor.inflate(buf);
bos.write(buf, 0, count);
unCompressed = bos.toByteArray();
bos.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
deCompressor.end();
return unC
时间: February 7, 2016
工具的时候,发现当并发比较高的时候程序占用的内存会飙升,而且在中断压测之后,内存占用并没有回落。第一个能想到的办法就是去看代码,但是大多数时候,自己写的代码,很难review出太多的问题;于是就借助golang的pprof来定位问题。在程序中嵌入 pprofpackage main
&tool.lu/sandbox-server/app&
&net/http&
_ &net/http/pprof&
func main() {
server := app.NewApp()
server.Run(&:9090&)
func debug() {
go func() {
// 这边是由于通过pprof发现问题之后,加的一段debug代码;后面会讲到
http.HandleFunc(&/go&, func(w http.ResponseWriter, r *http.Request) {
num := strconv.FormatInt(int64(runtime.NumGoroutine()), 10)
w.Write([]byte(num))
http.ListenAndServe(&localhost:6060&, nil)
}通过 go tool 工具,查看内存分配最多的 top 5go tool pprof http://localhost:6060/debug/pprof/heap
top 5查看代码,发现是 goroutine, ioPipe 的问题,一定是使用姿势出了问题:于是便有了上面的那段代码,curl http://localhost:6060/go,查看当前 go routine 的数量;于是猜测是因为 ioPipe 没有正确的关闭,引起 go routine 大量的产生,但是没有退出,耗费大量的内存;于是在异常退出前,主动关闭 ioPipe 的Reader,至此问题解决。压测验证本机wrk -t5 -c20 -d10000s -s post.lua http://tool.lu服务器curl http://localhost:6060/go总结这是一个很小的bug,由于写代码的时候不仔细,return之前没有关闭资源造成,但却要花费不少的力气去解决;对语言自己提供的工具链需要熟悉在熟悉,这样不管在解决问题或者避免问题的时候,都能节省很多的时间。
时间: December 27, 2015
设置环境变量export $LANG=&UTF-8&设置tomcat接收GET参数时候的编码 server.xml (tomcat中的配置文件)&Connector
URIEncoding=&UTF-8&&设置接收POST参数时候的编码web工程中web.xml的设置必须要放在所有filter之前
&filter-name&encodingFilter&/filter-name&
&filter-class&org.springframework.web.filter.CharacterEncodingFilter&/filter-class&
&init-param&
&param-name&encoding&/param-name&
&param-value&UTF-8&/param-value&
&/init-param&
&filter-mapping&
&filter-name&encodingFilter&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
: 代码都在文章中,很简单的两个函数,还需要什么使用方法?
: 请问有没有具体使用方法
: 哎呦,方法不错现在业务不是很大,都是停机迁移的
: 初始化editor那里 不太明白,能详解一下吗 谢谢
: 呃,这个没用过,不清楚了,我以为wp呢
: 如果是对value进行排序呢
: 插件不分sb版本
: 求sublime text 3的
: 你有laracasts的优惠券吗}

我要回帖

更多关于 封装是什么 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信