CC's blog

CC的技术博客 专注于 it 互联网的技术爱好者

React-Native 环境搭建

下面将以Mac OS为例:

  • 安装Homebrew   mac  软件包管理工具
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • 如果遇到  /user/local不可读写则执行
sudo chown -R `whoami` /usr/local
  • 使用Homebrew 来安装  Node.js
brew install node
  • 接下来 安装react native 命令行工具   react-native-cli
npm install -g react-native-cli
  • 安装Xcode  及其命令行工具  一般xcode安装成功  xcode  

Command Line Tools   便自动安装成功

推荐安装watchman

Watchman是由Facebook提供的监视文件系统变更的工具。安装此工具可以提高开发时的性能(packager可以快速捕捉文件的变化从而实现实时刷新)。</span>

brew install watchman

Flow

Flow是一个静态的JS类型检查工具。译注:你在很多示例中看到的奇奇怪怪的冒号问号,以及方法参数中像类型一样的写法,都是属于这个flow工具的语法。这一语法并不属于ES标准,只是Facebook自家的代码规范。所以新手可以直接跳过(即不需要安装这一工具,也不建议去费力学习flow相关语法)。

brew install flow

执行以下命令  测试创建一个app  并进入目录执行

react-native init AwesomeProject
cd AwesomeProject
react-native run-iso
阅读全文
none

Runtime 详解

什么是Runtime

  • 我们写的代码在程序运行过程中都会被转化成runtime的C代码执行,

例如

[target doSomething];

会被转化成:

objc_msgSend(target, @selector(doSomething));

OC中一切都被设计成了对象,我们都知道一个类被初始化成一个实例,这个实例是一个对象。实际上一个类本质上也是一个对象,在runtime中用结构体表示。

相关的定义:

    /// 描述类中的一个方法
    typedef struct objc_method *Method;

    /// 实例变量
    typedef struct objc_ivar *Ivar;

    /// 类别Category
    typedef struct objc_category *Category;

    /// 类中声明的属性
    typedef struct objc_property *objc_property_t;

类在runtime中的表示

  //类在runtime中的表示
  struct objc_class {
      Class isa;//指针,顾名思义,表示是一个什么,
      //实例的isa指向类对象,类对象的isa指向元类

  #if !__OBJC2__
      Class super_class;  //指向父类
      const char *name;  //类名
      long version;
      long info;
      long instance_size
      struct objc_ivar_list *ivars //成员变量列表
      struct objc_method_list **methodLists; //方法列表
      struct objc_cache *cache;//缓存
      //一种优化,调用过的方法存入缓存列表,下次调用先找缓存
      struct objc_protocol_list *protocols //协议列表
      #endif
  } OBJC2_UNAVAILABLE;
  /* Use `Class` instead of `struct objc_class *` */

获取列表

有时候会有这样的需求,我们需要知道当前类中每个属性的名字(比如字典转模型,字典的Key和模型对象的属性名字不匹配)。

我们可以通过runtime的一系列方法获取类的一些信息(包括属性列表,方法列表,成员变量列表,和遵循的协议列表)。

  unsigned int count;
    //获取属性列表
    objc_property_t *propertyList = class_copyPropertyList([self class], &count);
    for (unsigned int i=0; i<count; i++) {
        const char *propertyName = property_getName(propertyList[i]);
        NSLog(@"property---->%@", [NSString stringWithUTF8String:propertyName]);
    }

    //获取方法列表
    Method *methodList = class_copyMethodList([self class], &count);
    for (unsigned int i; i<count; i++) {
        Method method = methodList[i];
        NSLog(@"method---->%@", NSStringFromSelector(method_getName(method)));
    }

    //获取成员变量列表
    Ivar *ivarList = class_copyIvarList([self class], &count);
    for (unsigned int i; i<count; i++) {
        Ivar myIvar = ivarList[i];
        const char *ivarName = ivar_getName(myIvar);
        NSLog(@"Ivar---->%@", [NSString stringWithUTF8String:ivarName]);
    }

    //获取协议列表
    __unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);
    for (unsigned int i; i<count; i++) {
        Protocol *myProtocal = protocolList[i];
        const char *protocolName = protocol_getName(myProtocal);
        NSLog(@"protocol---->%@", [NSString stringWithUTF8String:protocolName]);
    }

在Xcode上跑一下看看输出吧,需要给你当前的类写几个属性,成员变量,方法和协议,不然获取的列表是没有东西的。

注意,调用这些获取列表的方法别忘记导入头文件#import。

方法调用

让我们看一下方法调用在运行时的过程(参照前文类在runtime中的表示)

如果用实例对象调用实例方法,会到实例的isa指针指向的对象(也就是类对象)操作。
如果调用的是类方法,就会到类对象的isa指针指向的对象(也就是元类对象)中操作。

首先,在相应操作的对象中的缓存方法列表中找调用的方法,如果找到,转向相应实现并执行。
如果没找到,在相应操作的对象中的方法列表中找调用的方法,如果找到,转向相应实现执行
如果没找到,去父类指针所指向的对象中执行1,2.
以此类推,如果一直到根类还没找到,转向拦截调用。
如果没有重写拦截调用的方法,程序报错。
以上的过程给我带来的启发:

重写父类的方法,并没有覆盖掉父类的方法,只是在当前类对象中找到了这个方法后就不会再去父类中找了。
如果想调用已经重写过的方法的父类的实现,只需使用super这个编译器标识,它会在运行时跳过在当前的类对象中寻找方法的过程。
拦截调用

在方法调用中说到了,如果没有找到方法就会转向拦截调用。

那么什么是拦截调用呢。

拦截调用就是,在找不到调用的方法程序崩溃之前,你有机会通过重写NSObject的四个方法来处理。

+ (BOOL)resolveClassMethod:(SEL)sel;
+ (BOOL)resolveInstanceMethod:(SEL)sel;
//后两个方法需要转发到其他的类处理
- (id)forwardingTargetForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)anInvocation;

第一个方法是当你调用一个不存在的类方法的时候,会调用这个方法,默认返回NO,你可以加上自己的处理然后返回YES。
第二个方法和第一个方法相似,只不过处理的是实例方法。
第三个方法是将你调用的不存在的方法重定向到一个其他声明了这个方法的类,只需要你返回一个有这个方法的target。
第四个方法是将你调用的不存在的方法打包成NSInvocation传给你。做完你自己的处理后,调用invokeWithTarget:方法让某个target触发这个方法。
动态添加方法

重写了拦截调用的方法并且返回了YES,我们要怎么处理呢?
有一个办法是根据传进来的SEL类型的selector动态添加一个方法。

首先从外部隐式调用一个不存在的方法:

//隐式调用方法
[target performSelector:@selector(resolveAdd:) withObject:@"test"];
然后,在target对象内部重写拦截调用的方法,动态添加方法。

void runAddMethod(id self, SEL _cmd, NSString *string){
    NSLog(@"add C IMP ", string);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel{

    //给本类动态添加一个方法
    if ([NSStringFromSelector(sel) isEqualToString:@"resolveAdd:"]) {
        class_addMethod(self, sel, (IMP)runAddMethod, "v@:*");
    }
    return YES;
}

其中class_addMethod的四个参数分别是:

Class cls 给哪个类添加方法,本例中是self
SEL name 添加的方法,本例中是重写的拦截调用传进来的selector。
IMP imp 方法的实现,C方法的方法实现可以直接获得。如果是OC方法,可以用+ (IMP)instanceMethodForSelector:(SEL)aSelector;获得方法的实现。
“v@:*”方法的签名,代表有一个参数的方法。
关联对象

现在你准备用一个系统的类,但是系统的类并不能满足你的需求,你需要额外添加一个属性。
这种情况的一般解决办法就是继承。

但是,只增加一个属性,就去继承一个类,总是觉得太麻烦类。

这个时候,runtime的关联属性就发挥它的作用了。

//首先定义一个全局变量,用它的地址作为关联对象的key
static char associatedObjectKey;
//设置关联对象
objc_setAssociatedObject(target, &associatedObjectKey, @"添加的字符串属性", OBJC_ASSOCIATION_RETAIN_NONATOMIC); //获取关联对象
NSString *string = objc_getAssociatedObject(target, &associatedObjectKey);
NSLog(@"AssociatedObject = %@", string);
objc_setAssociatedObject的四个参数:

id object给谁设置关联对象。
const void *key关联对象唯一的key,获取时会用到。
id value关联对象。
objc_AssociationPolicy关联策略,有以下几种策略:

enum {

 OBJC_ASSOCIATION_ASSIGN = 0,
 OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, 
 OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
 OBJC_ASSOCIATION_RETAIN = 01401,
 OBJC_ASSOCIATION_COPY = 01403 
};

如果你熟悉OC,看名字应该知道这几种策略的意思了吧。

objc_getAssociatedObject的两个参数。

id object获取谁的关联对象。
const void *key根据这个唯一的key获取关联对象。
其实,你还可以把添加和获取关联对象的方法写在你需要用到这个功能的类的类别中,方便使用。

//添加关联对象
- (void)addAssociatedObject:(id)object{
    objc_setAssociatedObject(self, @selector(getAssociatedObject), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
//获取关联对象
- (id)getAssociatedObject{
    return objc_getAssociatedObject(self, _cmd);
}

注意:这里面我们把getAssociatedObject方法的地址作为唯一的key,_cmd代表当前调用方法的地址。

方法交换

方法交换,顾名思义,就是将两个方法的实现交换。例如,将A方法和B方法交换,调用A方法的时候,就会执行B方法中的代码,反之亦然。
话不多说,这是参考Mattt大神在NSHipster上的文章自己写的代码。

#import "UIViewController+swizzling.h"
#import <objc/runtime.h>

@implementation UIViewController (swizzling)

//load方法会在类第一次加载的时候被调用
//调用的时间比较靠前,适合在这个方法里做方法交换
+ (void)load{
    //方法交换应该被保证,在程序中只会执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        //获得viewController的生命周期方法的selector
        SEL systemSel = @selector(viewWillAppear:);
        //自己实现的将要被交换的方法的selector
        SEL swizzSel = @selector(swiz_viewWillAppear:);
        //两个方法的Method
        Method systemMethod = class_getInstanceMethod([self class], systemSel);
        Method swizzMethod = class_getInstanceMethod([self class], swizzSel);

        //首先动态添加方法,实现是被交换的方法,返回值表示添加成功还是失败
        BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
        if (isAdd) {
            //如果成功,说明类中不存在这个方法的实现
            //将被交换方法的实现替换到这个并不存在的实现
            class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
        }else{
            //否则,交换两个方法的实现
            method_exchangeImplementations(systemMethod, swizzMethod);
        }

    });
}

- (void)swiz_viewWillAppear:(BOOL)animated{
    //这时候调用自己,看起来像是死循环
    //但是其实自己的实现已经被替换了
    [self swiz_viewWillAppear:animated];
    NSLog(@"swizzle");
}

@end
在一个自己定义的viewController中重写viewWillAppear

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    NSLog(@"viewWillAppear");
}
阅读全文

Repositories contributed to 没了 不显示

今天早上起来发现  Repositories contributed to  这一项凭空消失

原来是  github  为了可以自由展示主页新增了

Pin repositories


你可以点击

QQ20160617-0@2x.png

你可以点击  customize your pinned repositories  来显示你要展示那些项目  

包括你做过贡献的

当然你如果不设置的话  将会继续显示 most popular repositories

阅读全文

和你

如果你长的再丑一点

我会带你去咖啡厅坐下来

喝一杯咖啡双目对视

我会带你去游览名山大川

带你去吃最好吃的西餐

晚上走在马路上抬起头

看着星星聊聊人生

可是你长的这么漂亮

我只想和你睡觉


阅读全文
none

怎么在 linux 上搭建一个 nginx + rtmp 直播服务器

1.安装编译工具及库文件(使用yum命令安装)

yum install -y apr* autoconf automake bison bzip2 bzip2* cloog-ppl compat* cpp curl curl-devel fontconfig fontconfig-devel freetype freetype* freetype-devel gcc gcc-c++ gtk+-devel gd gettext gettext-devel glibc kernel kernel-headers keyutils keyutils-libs-devel krb5-devel libcom_err-devel libpng libpng* libpng-devel libjpeg* libsepol-devel libselinux-devel libstdc++-devel libtool* libgomp libxml2 libxml2-devel libXpm* libX* libtiff libtiff* make mpfr ncurses* ntp openssl nasm nasm* openssl-devel patch pcre-devel perl php-common php-gd policycoreutils ppl telnet t1lib t1lib* wget zlib-devel libxml2 libxml2-devel libxslt libxslt-devel unzip

2.源码下载

nginx源码

nginx-rtmp源码

3.解压源码

tar -zxvf ***.tar.gz

4.编译安装

cd nginx-1.10.2

./configure --add-module=../nginx-rtmp-module-master

make

sudo make install

5.环境配置

首先要做的(如果之前配置过nginx,比如反向代理),就是stop当前正在运行的nginx,并关闭开机自启动

/etc/init.d/nginx stop
chkconfig --level 2345 nginx off

之后流媒体服务器(点播、直播)的配置,参考http://lib.csdn.net/article/57/37915?knId=1549,不再重复造轮子

注意:点播支持flv、mp4 视频h264音频aac格式

6.ffmpeg测试命令

推流
ffmpeg -re -i test.avi -vcodec h264 -acodec aac -f flv rtmp://219.216.87.99/live/test1
转码
ffmpeg -i test.avi -acodec aac -vcodec h264 -f flv test.flv
7.开机自启

./usr/local/nginx/sbin/nginx

重点来了

在此视频直播的基础上,继续配置nginx反向代理

主要修改nginx.conf就可以实现,这里有个问题,就是配置rtmp时,使用了http服务器的部分,相当于主域名www会由配置流媒体服务器的那个http server响应。原来nginx只是作为反向代理,自己不提供内容。这样原来由apache响应的index就要交给nginx。

直接看配置吧

user  nginx;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}
rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        application vod {
            play /home/yourname/videoServer/vod;
        }
        application vod_http {
            #play http://video.yourname.cn/vod;
            play http://localhost/vod;
        }

        application live {
            live on;
        }

        application hls {
            live on;
            hls on;
            hls_path /home/yourname/videoServer/hls;
            wait_key on;
            hls_fragment 10s;
            hls_playlist_length 60s;
            hls_continuous on;
            hls_cleanup on;
            hls_nested on;
        }
    }
}


http {
    include       mime.types;
    default_type  application/octet-stream;

#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';

#access_log  logs/access.log  main;

    sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
    keepalive_timeout  65;

#gzip  on;

    server {
        listen       80;
        server_name  www.yourname.cn;

        location / {
            root   html;
            index  index.html index.htm;
        }
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
        location /stat.xsl {
            root /usr/local/nginx/livestats/;
        }

        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            add_header Cache-Control no-cache;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }



    upstream tomcat{
        server localhost:8081;
    }
    server {
        listen      80;
        server_name     tom.yourname.cn;
        location / {
            proxy_pass      http://tomcat;
            proxy_redirect      off;
            proxy_set_header    Host $host;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }

    upstream apache_index{
        server localhost:9080;
    }
    server {
        listen          80;
        server_name     video.yourname.cn;#此前这是www,现在变成二级域名
        location / {
            proxy_pass              http://apache_index;
            proxy_redirect          off;
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }


    upstream apache_blog{
        server localhost:9090;
    }
    server {
        listen          80; 
        server_name     blog.yourname.cn;
        location / {
            proxy_pass              http://apache_blog;
            proxy_redirect          off;
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }
    upstream apache_bbs{
        server localhost:9095;
    }
    server {
        listen          80;
        server_name     bbs.yourname.cn;
        location / {
            proxy_pass              http://apache_bbs;
            proxy_redirect          off;
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }

}
阅读全文

将日期转换成星期

NSDate *today=  [[NSDate alloc]init];
NSDateComponents*componets = [[NSCalendarautoupdatingCurrentCalendar]                
[components:NSCalendarUnitWeekdayfromDate:today];
NSIntegerweekday = [componetsweekday];
NSLog(@"%zd--------",weekday);
阅读全文
none

ffmpeg 桌面 摄像头 麦克风 推流 直播

<p>

<span style="color:#666666;font-family:Arial;font-size:medium;white-space:normal;background-color:#FFFFFF;">首先查看ffmpeg是否支持对应的设备,在OSX下面,Video和Audio设备使用的是avfoundation,所以可以使用avfoundation来查看</span> 

</p>
<p>

ffmpeg -f avfoundation -list_devices true -i ""

</p>
<p>

&nbsp;ffmpeg version 3.0.2 Copyright (c) 2000-2016 the FFmpeg developers

</p>

 
 built with Apple LLVM version 7.3.0 (clang-703.0.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.0.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --enable-vda
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
[AVFoundation input device @ 0x7fd602e00280] AVFoundation video devices:
[AVFoundation input device @ 0x7fd602e00280] [0] FaceTime HD Camera
[AVFoundation input device @ 0x7fd602e00280] [1] Capture screen 0
[AVFoundation input device @ 0x7fd602e00280] AVFoundation audio devices:
[AVFoundation input device @ 0x7fd602e00280] [0] Built-in Microphone


<span style="color:#666666;font-family:Arial;font-size:16px;white-space:normal;background-color:#FFFFFF;">通过输出内容可以看到,video部分支持的时两个设备</span>

<span style="color:#666666;font-family:Arial;font-size:16px;white-space:normal;background-color:#FFFFFF;">如果希望将桌面录制或者分享,可以使用命令行如下:</span>

ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -acodec libfaac -f flv
<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo;">
    flv rtmp://localhost:5920/rtmplive/room
</p>

<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo;">
    <span style="color:#666666;font-family:Arial;font-size:16px;white-space:normal;background-color:#FFFFFF;">如果需要桌面+麦克风,比如一般做远程教育分享ppt或者桌面,有音频讲解</span><span style="font-family:'sans serif', tahoma, verdana, helvetica;font-size:12px;"> </span> 
</p>

<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo;">
    <span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">ffmpeg </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">f avfoundation </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">i </span><span style="font-size:12px;word-wrap:break-word;color:#FF00FF;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">"1:0"</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;"> </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">vcodec libx264 </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">preset ultrafast </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">acodec libfaac </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">f flv</span><span style="font-family:'sans serif', tahoma, verdana, helvetica;font-size:12px;">   </span>rtmp://localhost:5920/rtmplive/room
</p>

<p style="margin-top:0px;margin-bottom:0px;font-size:11px;line-height:normal;font-family:Menlo;">
    <span style="color:#666666;font-family:Arial;font-size:16px;white-space:normal;background-color:#FFFFFF;">如果需要桌面+麦克风,并且还要摄像头拍摄到自己,比如一般用于互动主播,游戏主播,命令行如下</span> 
</p>
<span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">ffmpeg </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">f avfoundation </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">i </span><span style="font-size:12px;word-wrap:break-word;color:#FF00FF;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">"1:0"</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;"> </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">f avfoundation </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">i </span><span style="font-size:12px;word-wrap:break-word;color:#FF00FF;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">"0"</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;"> </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">filter_complex </span><span style="font-size:12px;word-wrap:break-word;color:#FF00FF;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">'overlay=10:main_h-overlay_h-10'</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;"> </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">vcodec libx264 </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">b</span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">:</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">v 800k </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">r</span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">:</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">v 25 </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">s 480x320 </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">preset ultrafast </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">acodec libfaac </span><span style="font-size:12px;word-wrap:break-word;color:#0000CC;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;">-</span><span style="font-size:12px;font-family:Consolas, monospace;letter-spacing:0.10000000149011612px;white-space:normal;background-color:#FFFFFF;">f flv </span>
rtmp://localhost:5920/rtmplive/room
阅读全文
none

tableview 头部视图图片下拉放大

原理 给tableview添加一个背景图 (Runtime 追加成员变量) ,header默认透明//

demo1.gif


//
//  url:https://www.xiongcaichang.com
//  Created by bear on 16/3/31.
//  Copyright © 2016年 bear. All rights reserved.
//
#import <UIKit/UIKit.h>


static const CGFloat MaxHeight = 200;



@interface ScalableCover : UIImageView

@property (nonatomic, strong) UIScrollView *scrollView;

@end




@interface UIScrollView (ScalableCover)

@property (nonatomic, weak) ScalableCover *scalableCover;

- (void)addScalableCoverWithImage:(UIImage *)image;
- (void)removeScalableCover;

@end
//
//
//
//  url:https://www.xiongcaichang.com
//  Created by bear on 16/3/31.
//  Copyright © 2016年 bear. All rights reserved.
//



#import "UIScrollView+ScalableCover.h"
#import 

static NSString * const kContentOffset = @"contentOffset";
static NSString * const kScalableCover = @"scalableCover";

@implementation UIScrollView (ScalableCover)

- (void)setScalableCover:(ScalableCover *)scalableCover
{
    [self willChangeValueForKey:kScalableCover];
    objc_setAssociatedObject(self, @selector(scalableCover),
                             scalableCover,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self didChangeValueForKey:kScalableCover];
}

- (ScalableCover *)scalableCover
{
    return objc_getAssociatedObject(self, &kScalableCover);
}

- (void)addScalableCoverWithImage:(UIImage *)image
{
    ScalableCover *cover = [[ScalableCover alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, MaxHeight)];
    
    cover.backgroundColor = [UIColor clearColor];
    cover.image = image;
    cover.scrollView = self;
    
    [self addSubview:cover];
    [self sendSubviewToBack:cover];
    
    self.scalableCover = cover;
}

- (void)removeScalableCover
{
    [self.scalableCover removeFromSuperview];
    self.scalableCover = nil;
}


@end




@interface ScalableCover (){

}



@end


@implementation ScalableCover

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.contentMode = UIViewContentModeScaleAspectFill;
        self.clipsToBounds = YES;

    }

    return self;
}


- (void)setScrollView:(UIScrollView *)scrollView
{

    [_scrollView removeObserver:scrollView forKeyPath:kContentOffset];
    _scrollView = scrollView;
    [_scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}




- (void)removeFromSuperview
{
    [_scrollView removeObserver:self forKeyPath:@"contentOffset"];
    [super removeFromSuperview];
}




- (void)layoutSubviews
{
    [super layoutSubviews];
    
    if (self.scrollView.contentOffset.y < 0) {
 CGFloat offset = -self.scrollView.contentOffset.y;
 self.frame = CGRectMake(-offset, -offset, _scrollView.bounds.size.width + offset * 2, MaxHeight + offset);
 } else {
 self.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, MaxHeight); 
}
 } 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
[self setNeedsLayout]; 
} 
@end 


未完代码详见demo  点击下载:TableViewScaleableHeader.zip

阅读全文
none

2016-04-07 Google Host (Host定期更新,还请亲们注意保存书签)

使用方法

Widonws系统:

到C:\windows\system32\drivers\etc下查找hosts文件并以记事本打开,然后复制以下谷歌-Hosts代码进去,最后保存。(记得文件是无后缀的哦!)

Linux系统

请修改/etc/hosts这个文件

安卓

同上,但要ROOT

MAC系统

如果是苹果电脑请打开你的文件管理器(也就是finder)然后,请按快捷键组合 Shift+Command+G三个组合按键查找文件,并输入Hosts文件的所在路径:/etc/hosts文件。  用sublime或者非系统文本编辑器将下载的内容粘贴进去  保存
阅读全文
none