精华内容
下载资源
问答
  • ae和ame关联

    2018-04-23 11:09:35
    此方法用于AE和AME自动关联失败的情况 故剑 为什么要把AE 和AME 关联?因为AE 内置输出格式存在限制,如Pr 能导出的 H.264它都没有,但如果关联AME就能以更多的格式输出,能够有效减小输出时间 和输出文件的大小
  • Ae入门学习笔记

    千次阅读 多人点赞 2019-10-05 21:33:41
    Ae入门学习笔记 参考:【AE】After Effects CC 2019全套入门教程 Ae CC2019全套课程资料: https://pan.baidu.com/s/1hqQhpBg9mxw1IJAmRLav7A#list/path=%2F 提取码:58f8 ...时间轴之文字模糊与发光 P5 5.下雨...

    Ae入门学习笔记

    参考:【AE】After Effects CC 2019全套入门教程


    Ae CC2019全套课程资料:
    链接:https://pan.baidu.com/s/1pNiNRZk7_bxmchiBqy_M_w
    提取码:ajh0


    P1 1.AE界面介绍和窗口布局

    Alt

      显示面板在【窗口】中设置,恢复默认可以设置【窗口】→【工作区】→【默认】,然后选择【默认】→【重置为已保存的布局】

    P2 2.简单动画

      新建合成(该合成设置之后可在【合成】→【合成设置】中调整),然后在时间轴窗口左侧中设置相关属性,选中对应素材在菜单栏中选择【效果】可以添加对应的特效。

      制作后按 0 键自动播放

      制作导出:【文件】→【导出】→【添加到渲染队列】,然后在时间轴窗口中【最佳设置】一般不改动,【无损】中的格式建议更改为 QuickTime,设置 【输出到】(位置和命名),最后点击【渲染】。

    P3 3.素材的导入
    1. 准备素材

    图片、PSD、视频、音频(注意版权、尺寸)

    1. 导入素材

    注意序列的选择,选中的话会将所有类似命名的一起导入为连图。

    四种导入方式:文件菜单、右键、双击、缩小拖入

    1. 管理素材

    分类整理,文件夹

    P4 4.时间轴之文字模糊与发光

      先新建合成,然后左下角新建文本,输入文本,点击颜色旁边的右三角,然后设置位置,即可制定自定义文本移动。

      选中文本,设置特效(本节演示CC Light Rays),【效果】→【生成】→【CC Light Rays】,或者在合成窗口右侧【效果和预设】中输入搜索即可。相关属性在 项目窗口 中设置。

      设置一定的效果后可以选中该图层,然后【图层】→【预合成】

      最后导出即可。

    P5 5.下雨效果

      效果 → 模拟 → CC Rainfall

    P6 6.AE模板的使用

      AE模板_新CG儿 - 数字视觉分享平台 | AE模板_视频素材_免费下载

      软件版本 + 插件要求 + 使用帮助

    P7 7.saber插件的使用
    1. 下载

      百度搜索 saber插件 下载即可。

    1. 安装

      安装中直接运行 SaberInstaller_1.0.39_Win.exe ,在安装中 选中Custom,Browse选择安装目录 ……\Adobe After Effects CC 2018\Support Files\Plug-ins

    1. 使用

      安装完成后需要重启软件才能生效

      新建文本,新建纯色(选中 制作合成大小)

      【效果】→【Video Copilot】→【Saber】

      左上角的效果控件中可以调整相关属性。Glow Intensity可以调整亮度,选择Customize Core中,Core Type设置Text Layer,然后选择之前新建的文本,接下来就可以设置想要的关键帧动画。

      之后可以导入视频,点击 切换开关/模式 ,选中文本模式设置为 屏幕,可以将刚才设置的文字显示在视频上面。

    P8 8.图层面板及关键帧动画

      选中图层面板中的图片1按住“Ctrl+D”就多出来图片1,选中多出来的图片1按住“Alt”键把图片2拖到图片1;1就变成2了。这样就保留了原有样式设置。

      关键帧动画三点:开始时间、变化、结束时间

    P9 9.遮罩效果

      蒙版效果,两张相同的图片,不同处理,前后覆盖,利用图形的蒙版效果显示。

    P10 10.抠像技术
    1. 笔刷工具,在图层面板中按住“Alt”键拖动把所需要的图像抠下来;
    2. 选中图片图层,找到【效果】里的【抠图】中的颜色范围;
    3. Keying→Keylight工具。
    P11 11.E3D安装及制作立体文字
    P12 12.三维合成实现天气预告

      三维使用(三维图层按钮,在 切换开关/模式 中可以看到),摄像机工具,关键帧动画

      图片不方便查看,可以锁定图层,然后新建摄像机,预设50毫米,不启用景深。

    P13 13.二维合成
    P14 14.电视广告设计
    P15 15.综合实例游戏场景制作
    P16 16.AE输出及小结
    1. Media Encoder CC

      文件格式处理,在Ae中选择【文件】→【导出】→【添加到Adobe Media Encoder 队列】,然后利用Media Encoder工具进行格式处理。

    1. 导出为mp4格式

      AfterCodecs插件工具,在导出时【无损】中的格式可以选择【AfterCodecs.mp4】,格式选项中可以注册改插件。

    1. 学习小结
    • 一般尽量用最新的版本,电脑能支撑的最新版;
    • 插件使用看需求,重点在于如何做到最佳效果,表达出想要表达的效果即可,而不是说一定要用多少多少插件;
    • 多实践。

    展开全文
  • ae事件库

    千次阅读 2014-07-02 16:00:49
    #ifndef __AE_H__ #define __AE_H__ #include #include /* * 事件执行状态 */ #define AE_OK 0 // 成功 #define AE_ERR -1 // 出错 /* * 文件事件状态 */ #define AE_NONE 0 // 未设置 #define AE_READABLE 1 /...
    #ifndef __AE_H__
    #define __AE_H__
    
    #include <time.h>
    #include <stdlib.h>
    
    /*
    * 事件执行状态
    */
    #define AE_OK 0     // 成功
    #define AE_ERR -1   // 出错
    
    /*
    * 文件事件状态
    */
    #define AE_NONE 0       // 未设置
    #define AE_READABLE 1   // 可读
    #define AE_WRITABLE 2   // 可写
    
    /*
    * 时间处理器的执行 flags
    */
    #define AE_FILE_EVENTS 1
    #define AE_TIME_EVENTS 2
    #define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS)
    #define AE_DONT_WAIT 4
    
    /*
    * 决定时间事件是否要持续执行的 flag
    */
    #define AE_NOMORE -1
    
    /* Macros */
    #define AE_NOTUSED(V) ((void) V)
    
    /*
    * 事件处理器状态
    */
    struct aeEventLoop;
    
    /* Types and data structures */
    typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);
    typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);
    typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);
    typedef void aeBeforeSleepProc(struct aeEventLoop *eventLoop);
    
    /* File event structure
    *
    * 文件事件结构
    */
    typedef struct aeFileEvent {
    	// 事件类型掩码,值可以是 AE_READABLE 或 AE_WRITABLE ,或者两者的或
    	int mask; /* one of AE_(READABLE|WRITABLE) */
    	// 写事件函数
    	aeFileProc *rfileProc;
    	// 读事件函数
    	aeFileProc *wfileProc;
    	// 多路复用库的私有数据
    	void *clientData;
    } aeFileEvent;
    
    /* Time event structure
    *
    * 时间事件结构
    */
    typedef struct aeTimeEvent {
    
    	// 时间事件的唯一标识符
    	long long id; /* time event identifier. */
    
    	// 事件的到达时间
    	long when_sec; /* seconds */
    	long when_ms; /* milliseconds */
    
    	// 事件处理函数
    	aeTimeProc *timeProc;
    
    	// 事件释放函数
    	aeEventFinalizerProc *finalizerProc;
    
    	// 多路复用库的私有数据
    	void *clientData;
    
    	// 指向下个时间事件结构,形成链表
    	struct aeTimeEvent *next;
    
    } aeTimeEvent;
    
    /* A fired event
    *
    * 已就绪事件
    */
    typedef struct aeFiredEvent {
    	// 已就绪文件描述符
    	int fd;
    	// 事件类型掩码,可以是 AE_READABLE 或 AE_WRITABLE
    	int mask;
    } aeFiredEvent;
    
    /* State of an event based program 
    *
    * 事件处理器的状态
    */
    typedef struct aeEventLoop {
    	// 目前已注册的最大描述符
    	int maxfd;   /* highest file descriptor currently registered */
    	// 目前已追踪的最大描述符
    	int setsize; /* max number of file descriptors tracked */
    	// 用于生成时间事件 id
    	long long timeEventNextId;
    	// 最后一次执行时间事件的时间
    	time_t lastTime;     /* Used to detect system clock skew */
    	// 已注册的文件事件
    	aeFileEvent *events; /* Registered events */
    	// 已就绪的文件事件
    	aeFiredEvent *fired; /* Fired events */
    	// 时间事件
    	aeTimeEvent *timeEventHead;
    	// 事件处理器的开关
    	int stop;
    	// 多路复用库的私有数据
    	void *apidata; /* This is used for polling API specific data */
    	// 在处理事件前要执行的函数
    	aeBeforeSleepProc *beforesleep;
    } aeEventLoop;
    
    /* Prototypes */
    aeEventLoop *aeCreateEventLoop(int setsize);
    void aeDeleteEventLoop(aeEventLoop *eventLoop);
    void aeStop(aeEventLoop *eventLoop);
    int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
    					  aeFileProc *proc, void *clientData);
    void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask);
    int aeGetFileEvents(aeEventLoop *eventLoop, int fd);
    long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
    							aeTimeProc *proc, void *clientData,
    							aeEventFinalizerProc *finalizerProc);
    int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id);
    int aeProcessEvents(aeEventLoop *eventLoop, int flags);
    int aeWait(int fd, int mask, long long milliseconds);
    void aeMain(aeEventLoop *eventLoop);
    char *aeGetApiName(void);
    void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep);
    
    #endif<pre name="code" class="cpp">#define HAVE_EPOLL
    
    #include <stdio.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <poll.h>
    #include <string.h>
    #include <time.h>
    
    #include "ae.h"
    
    /* Include the best multiplexing layer supported by this system.
    * The following should be ordered by performances, descending. */
    #ifdef HAVE_EVPORT
    #include "ae_evport.c"
    #else
    #ifdef HAVE_EPOLL
    #include "ae_epoll.c"
    #else
    #ifdef HAVE_KQUEUE
    #include "ae_kqueue.c"
    #else
    #include "ae_select.c"
    #endif
    #endif
    #endif
    
    /*
    * 初始化事件处理器状态
    */
    aeEventLoop *aeCreateEventLoop(int setsize) {
    	aeEventLoop *eventLoop;
    	int i;
    
    	// 创建事件状态结构
    	if ((eventLoop = malloc(sizeof(*eventLoop))) == NULL) goto err;
    
    	// 初始化文件事件结构和已就绪文件事件结构
    	eventLoop->events = malloc(sizeof(aeFileEvent)*setsize);
    	eventLoop->fired = malloc(sizeof(aeFiredEvent)*setsize);
    	if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err;
    	eventLoop->setsize = setsize;
    	eventLoop->lastTime = time(NULL);
    
    	// 初始化时间事件结构
    	eventLoop->timeEventHead = NULL;
    	eventLoop->timeEventNextId = 0;
    
    	eventLoop->stop = 0;
    	eventLoop->maxfd = -1;
    	eventLoop->beforesleep = NULL;
    	if (aeApiCreate(eventLoop) == -1) goto err;
    	/* Events with mask == AE_NONE are not set. So let's initialize the
    	* vector with it. */
    	for (i = 0; i < setsize; i++)
    		eventLoop->events[i].mask = AE_NONE;
    	return eventLoop;
    
    err:
    	if (eventLoop) {
    		free(eventLoop->events);
    		free(eventLoop->fired);
    		free(eventLoop);
    	}
    	return NULL;
    }
    
    /*
    * 删除事件处理器
    */
    void aeDeleteEventLoop(aeEventLoop *eventLoop) {
    	aeApiFree(eventLoop);
    	free(eventLoop->events);
    	free(eventLoop->fired);
    	free(eventLoop);
    }
    
    /*
    * 停止事件处理器
    */
    void aeStop(aeEventLoop *eventLoop) {
    	eventLoop->stop = 1;
    }
    
    /*
    * 根据 mask 参数的值,监听 fd 文件的状态,
    * 当 fd 可用时,执行 proc 函数
    */
    int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
    					  aeFileProc *proc, void *clientData)
    {
    	if (fd >= eventLoop->setsize) return AE_ERR;
    	aeFileEvent *fe = &eventLoop->events[fd];
    
    	// 监听指定 fd
    	if (aeApiAddEvent(eventLoop, fd, mask) == -1)
    		return AE_ERR;
    
    	// 设置文件事件类型
    	fe->mask |= mask;
    	if (mask & AE_READABLE) fe->rfileProc = proc;
    	if (mask & AE_WRITABLE) fe->wfileProc = proc;
    
    	fe->clientData = clientData;
    
    	// 如果有需要,更新事件处理器的最大 fd
    	if (fd > eventLoop->maxfd)
    		eventLoop->maxfd = fd;
    
    	return AE_OK;
    }
    
    /*
    * 将 fd 从 mask 指定的监听队列中删除
    */
    void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
    {
    	if (fd >= eventLoop->setsize) return;
    	aeFileEvent *fe = &eventLoop->events[fd];
    
    	// 未设置监听的事件类型,直接返回
    	if (fe->mask == AE_NONE) return;
    
    	fe->mask = fe->mask & (~mask);
    	if (fd == eventLoop->maxfd && fe->mask == AE_NONE) {
    		/* Update the max fd */
    		int j;
    
    		for (j = eventLoop->maxfd-1; j >= 0; j--)
    			if (eventLoop->events[j].mask != AE_NONE) break;
    		eventLoop->maxfd = j;
    	}
    
    	// 取消监听给定 fd
    	aeApiDelEvent(eventLoop, fd, mask);
    }
    
    /*
    * 获取给定 fd 正在监听的事件类型
    */
    int aeGetFileEvents(aeEventLoop *eventLoop, int fd) {
    	if (fd >= eventLoop->setsize) return 0;
    	aeFileEvent *fe = &eventLoop->events[fd];
    
    	return fe->mask;
    }
    
    /*
    * 取出当前时间的秒和毫秒,
    * 并分别将它们保存到 seconds 和 milliseconds 参数中
    */
    static void aeGetTime(long *seconds, long *milliseconds)
    {
    	struct timeval tv;
    
    	gettimeofday(&tv, NULL);
    	*seconds = tv.tv_sec;
    	*milliseconds = tv.tv_usec/1000;
    }
    
    /*
    * 为当前时间加上 milliseconds 秒。
    */
    static void aeAddMillisecondsToNow(long long milliseconds, long *sec, long *ms) {
    	long cur_sec, cur_ms, when_sec, when_ms;
    
    	// 获取当前时间
    	aeGetTime(&cur_sec, &cur_ms);
    
    	// 计算增加 milliseconds 之后的秒数和毫秒数
    	when_sec = cur_sec + milliseconds/1000;
    	when_ms = cur_ms + milliseconds%1000;
    
    	// 进位:
    	// 如果 when_ms 大于等于 1000
    	// 那么将 when_sec 增大一秒
    	if (when_ms >= 1000) {
    		when_sec ++;
    		when_ms -= 1000;
    	}
    	*sec = when_sec;
    	*ms = when_ms;
    }
    
    /*
    * 创建时间事件
    */
    long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
    							aeTimeProc *proc, void *clientData,
    							aeEventFinalizerProc *finalizerProc)
    {
    	// 更新时间计数器
    	long long id = eventLoop->timeEventNextId++;
    	aeTimeEvent *te;
    
    	te = malloc(sizeof(*te));
    	if (te == NULL) return AE_ERR;
    
    	te->id = id;
    
    	// 设定处理事件的时间
    	aeAddMillisecondsToNow(milliseconds,&te->when_sec,&te->when_ms);
    	te->timeProc = proc;
    	te->finalizerProc = finalizerProc;
    	te->clientData = clientData;
    
    	// 将新事件放入表头
    	te->next = eventLoop->timeEventHead;
    	eventLoop->timeEventHead = te;
    
    	return id;
    }
    
    /*
    * 删除给定 id 的时间事件
    */
    int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id)
    {
    	aeTimeEvent *te, *prev = NULL;
    
    	te = eventLoop->timeEventHead;
    	while(te) {
    		if (te->id == id) {
    
    			if (prev == NULL)
    				eventLoop->timeEventHead = te->next;
    			else
    				prev->next = te->next;
    
    			if (te->finalizerProc)
    				te->finalizerProc(eventLoop, te->clientData);
    
    			free(te);
    
    			return AE_OK;
    		}
    		prev = te;
    		te = te->next;
    	}
    
    	return AE_ERR; /* NO event with the specified ID found */
    }
    
    /* Search the first timer to fire.
    * This operation is useful to know how many time the select can be
    * put in sleep without to delay any event.
    * If there are no timers NULL is returned.
    *
    * Note that's O(N) since time events are unsorted.
    * Possible optimizations (not needed by Redis so far, but...):
    * 1) Insert the event in order, so that the nearest is just the head.
    *    Much better but still insertion or deletion of timers is O(N).
    * 2) Use a skiplist to have this operation as O(1) and insertion as O(log(N)).
    */
    // 寻找里目前时间最近的时间事件
    // 因为链表是乱序的,所以查找复杂度为 O(N)
    static aeTimeEvent *aeSearchNearestTimer(aeEventLoop *eventLoop)
    {
    	aeTimeEvent *te = eventLoop->timeEventHead;
    	aeTimeEvent *nearest = NULL;
    
    	while(te) {
    		if (!nearest || te->when_sec < nearest->when_sec ||
    			(te->when_sec == nearest->when_sec &&
    			te->when_ms < nearest->when_ms))
    			nearest = te;
    		te = te->next;
    	}
    	return nearest;
    }
    
    /* Process time events
    *
    * 处理所有已到达的时间事件
    */
    static int processTimeEvents(aeEventLoop *eventLoop) {
    	int processed = 0;
    	aeTimeEvent *te;
    	long long maxId;
    	time_t now = time(NULL);
    
    	/* If the system clock is moved to the future, and then set back to the
    	* right value, time events may be delayed in a random way. Often this
    	* means that scheduled operations will not be performed soon enough.
    	*
    	* Here we try to detect system clock skews, and force all the time
    	* events to be processed ASAP when this happens: the idea is that
    	* processing events earlier is less dangerous than delaying them
    	* indefinitely, and practice suggests it is. */
    	// 通过重置事件的运行时间,
    	// 防止因时间穿插(skew)而造成的事件处理混乱
    	if (now < eventLoop->lastTime) {
    		te = eventLoop->timeEventHead;
    		while(te) {
    			te->when_sec = 0;
    			te = te->next;
    		}
    	}
    	// 更新最后一次处理时间事件的时间
    	eventLoop->lastTime = now;
    
    	te = eventLoop->timeEventHead;
    	maxId = eventLoop->timeEventNextId-1;
    	while(te) {
    		long now_sec, now_ms;
    		long long id;
    
    		// 跳过无效事件
    		if (te->id > maxId) {
    			te = te->next;
    			continue;
    		}
    
    		// 获取当前时间
    		aeGetTime(&now_sec, &now_ms);
    
    		// 如果当前时间等于或等于事件的执行时间,那么执行这个事件
    		if (now_sec > te->when_sec ||
    			(now_sec == te->when_sec && now_ms >= te->when_ms))
    		{
    			int retval;
    
    			id = te->id;
    			retval = te->timeProc(eventLoop, id, te->clientData);
    			processed++;
    			/* After an event is processed our time event list may
    			* no longer be the same, so we restart from head.
    			* Still we make sure to don't process events registered
    			* by event handlers itself in order to don't loop forever.
    			* To do so we saved the max ID we want to handle.
    			*
    			* FUTURE OPTIMIZATIONS:
    			* Note that this is NOT great algorithmically. Redis uses
    			* a single time event so it's not a problem but the right
    			* way to do this is to add the new elements on head, and
    			* to flag deleted elements in a special way for later
    			* deletion (putting references to the nodes to delete into
    			* another linked list). */
    
    			// 记录是否有需要循环执行这个事件时间
    			if (retval != AE_NOMORE) {
    				// 是的, retval 毫秒之后继续执行这个时间事件
    				aeAddMillisecondsToNow(retval,&te->when_sec,&te->when_ms);
    			} else {
    				// 不,将这个事件删除
    				aeDeleteTimeEvent(eventLoop, id);
    			}
    
    			// 因为执行事件之后,事件列表可能已经被改变了
    			// 因此需要将 te 放回表头,继续开始执行事件
    			te = eventLoop->timeEventHead;
    		} else {
    			te = te->next;
    		}
    	}
    	return processed;
    }
    
    /* Process every pending time event, then every pending file event
    * (that may be registered by time event callbacks just processed).
    *
    * 处理所有已到达的时间事件,以及所有已就绪的文件事件。
    *
    * Without special flags the function sleeps until some file event
    * fires, or when the next time event occurrs (if any).
    *
    * 如果不传入特殊 flags 的话,那么函数睡眠直到文件事件就绪,
    * 或者下个时间事件到达(如果有的话)。
    *
    * If flags is 0, the function does nothing and returns.
    * 如果 flags 为 0 ,那么函数不作动作,直接返回。
    *
    * if flags has AE_ALL_EVENTS set, all the kind of events are processed.
    * 如果 flags 包含 AE_ALL_EVENTS ,所有类型的事件都会被处理。
    *
    * if flags has AE_FILE_EVENTS set, file events are processed.
    * 如果 flags 包含 AE_FILE_EVENTS ,那么处理文件事件。
    *
    * if flags has AE_TIME_EVENTS set, time events are processed.
    * 如果 flags 包含 AE_TIME_EVENTS ,那么处理时间事件。
    *
    * if flags has AE_DONT_WAIT set the function returns ASAP until all
    * the events that's possible to process without to wait are processed.
    * 如果 flags 包含 AE_DONT_WAIT ,
    * 那么函数在处理完所有不许阻塞的事件之后,即刻返回。
    *
    * The function returns the number of events processed. 
    * 函数的返回值为已处理事件的数量
    */
    int aeProcessEvents(aeEventLoop *eventLoop, int flags)
    {
    	int processed = 0, numevents;
    
    	/* Nothing to do? return ASAP */
    	if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) return 0;
    
    	/* Note that we want call select() even if there are no
    	* file events to process as long as we want to process time
    	* events, in order to sleep until the next time event is ready
    	* to fire. */
    	if (eventLoop->maxfd != -1 ||
    		((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) {
    			int j;
    			aeTimeEvent *shortest = NULL;
    			struct timeval tv, *tvp;
    
    			// 获取最近的时间事件
    			if (flags & AE_TIME_EVENTS && !(flags & AE_DONT_WAIT))
    				shortest = aeSearchNearestTimer(eventLoop);
    			if (shortest) {
    				// 如果时间事件存在的话
    				// 那么根据最近可执行时间事件和现在时间的时间差来决定文件事件的阻塞时间
    				long now_sec, now_ms;
    
    				/* Calculate the time missing for the nearest
    				* timer to fire. */
    				// 计算距今最近的时间事件还要多久才能达到
    				// 并将该时间距保存在 tv 结构中
    				aeGetTime(&now_sec, &now_ms);
    				tvp = &tv;
    				tvp->tv_sec = shortest->when_sec - now_sec;
    				if (shortest->when_ms < now_ms) {
    					tvp->tv_usec = ((shortest->when_ms+1000) - now_ms)*1000;
    					tvp->tv_sec --;
    				} else {
    					tvp->tv_usec = (shortest->when_ms - now_ms)*1000;
    				}
    
    				// 时间差小于 0 ,说明事件已经可以执行了,将秒和毫秒设为 0 (不阻塞)
    				if (tvp->tv_sec < 0) tvp->tv_sec = 0;
    				if (tvp->tv_usec < 0) tvp->tv_usec = 0;
    			} else {
    
    				// 执行到这一步,说明没有时间事件
    				// 那么根据 AE_DONT_WAIT 是否设置来决定是否阻塞,以及阻塞的时间长度
    
    				/* If we have to check for events but need to return
    				* ASAP because of AE_DONT_WAIT we need to se the timeout
    				* to zero */
    				if (flags & AE_DONT_WAIT) {
    					// 设置文件事件不阻塞
    					tv.tv_sec = tv.tv_usec = 0;
    					tvp = &tv;
    				} else {
    					/* Otherwise we can block */
    					// 文件事件可以阻塞直到有事件到达为止
    					tvp = NULL; /* wait forever */
    				}
    			}
    
    			// 处理文件事件,阻塞时间由 tvp 决定
    			numevents = aeApiPoll(eventLoop, tvp);
    			for (j = 0; j < numevents; j++) {
    				// 从已就绪数组中获取事件
    				aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
    
    				int mask = eventLoop->fired[j].mask;
    				int fd = eventLoop->fired[j].fd;
    				int rfired = 0;
    
    				/* note the fe->mask & mask & ... code: maybe an already processed
    				* event removed an element that fired and we still didn't
    				* processed, so we check if the event is still valid. */
    				if (fe->mask & mask & AE_READABLE) {
    					// 读事件
    					rfired = 1; // 确保读/写事件只能执行其中一个
    					fe->rfileProc(eventLoop,fd,fe->clientData,mask);
    				}
    				if (fe->mask & mask & AE_WRITABLE) {
    					// 写事件
    					if (!rfired || fe->wfileProc != fe->rfileProc)
    						fe->wfileProc(eventLoop,fd,fe->clientData,mask);
    				}
    
    				processed++;
    			}
    	}
    
    	/* Check time events */
    	// 执行时间事件
    	if (flags & AE_TIME_EVENTS)
    		processed += processTimeEvents(eventLoop);
    
    	return processed; /* return the number of processed file/time events */
    }
    
    /* Wait for millseconds until the given file descriptor becomes
    * writable/readable/exception */
    int aeWait(int fd, int mask, long long milliseconds) {
    	struct pollfd pfd;
    	int retmask = 0, retval;
    
    	memset(&pfd, 0, sizeof(pfd));
    	pfd.fd = fd;
    	if (mask & AE_READABLE) pfd.events |= POLLIN;
    	if (mask & AE_WRITABLE) pfd.events |= POLLOUT;
    
    	if ((retval = poll(&pfd, 1, milliseconds))== 1) {
    		if (pfd.revents & POLLIN) retmask |= AE_READABLE;
    		if (pfd.revents & POLLOUT) retmask |= AE_WRITABLE;
    		if (pfd.revents & POLLERR) retmask |= AE_WRITABLE;
    		if (pfd.revents & POLLHUP) retmask |= AE_WRITABLE;
    		return retmask;
    	} else {
    		return retval;
    	}
    }
    
    // 事件处理器的主循环
    void aeMain(aeEventLoop *eventLoop) {
    
    	eventLoop->stop = 0;
    
    	while (!eventLoop->stop) {
    
    		// 如果有需要在事件处理前执行的函数,那么运行它
    		if (eventLoop->beforesleep != NULL)
    			eventLoop->beforesleep(eventLoop);
    
    		// 开始处理事件
    		aeProcessEvents(eventLoop, AE_ALL_EVENTS);
    	}
    }
    
    // 返回所使用的多路复用库的名称
    char *aeGetApiName(void) {
    	return aeApiName();
    }
    
    // 设置处理事件前需要被执行的函数
    void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep) {
    	eventLoop->beforesleep = beforesleep;
    }
    

    #include <sys/epoll.h>
    #include "ae.h"
    
    typedef struct aeApiState {
    	int epfd;
    	struct epoll_event *events;
    } aeApiState;
    
    static int aeApiCreate(aeEventLoop *eventLoop) {
    	aeApiState *state = malloc(sizeof(aeApiState));
    
    	if (!state) return -1;
    	state->events = malloc(sizeof(struct epoll_event)*eventLoop->setsize);
    	if (!state->events) {
    		free(state);
    		return -1;
    	}
    	state->epfd = epoll_create(1024); /* 1024 is just an hint for the kernel */
    	if (state->epfd == -1) {
    		free(state->events);
    		free(state);
    		return -1;
    	}
    	eventLoop->apidata = state;
    	return 0;
    }
    
    static void aeApiFree(aeEventLoop *eventLoop) {
    	aeApiState *state = eventLoop->apidata;
    
    	close(state->epfd);
    	free(state->events);
    	free(state);
    }
    
    static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
    	aeApiState *state = eventLoop->apidata;
    	struct epoll_event ee;
    	/* If the fd was already monitored for some event, we need a MOD
    	* operation. Otherwise we need an ADD operation. */
    	int op = eventLoop->events[fd].mask == AE_NONE ?
    EPOLL_CTL_ADD : EPOLL_CTL_MOD;
    
    	ee.events = 0;
    	mask |= eventLoop->events[fd].mask; /* Merge old events */
    	if (mask & AE_READABLE) ee.events |= EPOLLIN;
    	if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
    	ee.data.u64 = 0; /* avoid valgrind warning */
    	ee.data.fd = fd;
    	if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
    	return 0;
    }
    
    static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
    	aeApiState *state = eventLoop->apidata;
    	struct epoll_event ee;
    	int mask = eventLoop->events[fd].mask & (~delmask);
    
    	ee.events = 0;
    	if (mask & AE_READABLE) ee.events |= EPOLLIN;
    	if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
    	ee.data.u64 = 0; /* avoid valgrind warning */
    	ee.data.fd = fd;
    	if (mask != AE_NONE) {
    		epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
    	} else {
    		/* Note, Kernel < 2.6.9 requires a non null event pointer even for
    		* EPOLL_CTL_DEL. */
    		epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
    	}
    }
    
    static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
    	aeApiState *state = eventLoop->apidata;
    	int retval, numevents = 0;
    
    	retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
    		tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
    	if (retval > 0) {
    		int j;
    
    		numevents = retval;
    		for (j = 0; j < numevents; j++) {
    			int mask = 0;
    			struct epoll_event *e = state->events+j;
    
    			if (e->events & EPOLLIN) mask |= AE_READABLE;
    			if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
    			if (e->events & EPOLLERR) mask |= AE_WRITABLE;
    			if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
    			eventLoop->fired[j].fd = e->data.fd;
    			eventLoop->fired[j].mask = mask;
    		}
    	}
    	return numevents;
    }
    
    static char *aeApiName(void) {
    	return "epoll";
    }
    

    #ifndef ANET_H
    #define ANET_H
    
    #define ANET_OK 0
    #define ANET_ERR -1
    #define ANET_ERR_LEN 256
    
    int anetTcpConnect(char *err, char *addr, int port);
    int anetTcpNonBlockConnect(char *err, char *addr, int port);
    int anetUnixConnect(char *err, char *path);
    int anetUnixNonBlockConnect(char *err, char *path);
    int anetRead(int fd, char *buf, int count);
    int anetResolve(char *err, char *host, char *ipbuf);
    int anetTcpServer(char *err, int port, char *bindaddr);
    int anetUnixServer(char *err, char *path, mode_t perm);
    int anetTcpAccept(char *err, int serversock, char *ip, int *port);
    int anetUnixAccept(char *err, int serversock);
    int anetWrite(int fd, char *buf, int count);
    int anetNonBlock(char *err, int fd);
    int anetTcpNoDelay(char *err, int fd);
    int anetTcpKeepAlive(char *err, int fd);
    int anetPeerToString(int fd, char *ip, int *port);
    
    #endif
    

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/stat.h>
    #include <sys/un.h>
    #include <netinet/in.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <string.h>
    #include <netdb.h>
    #include <errno.h>
    #include <stdarg.h>
    #include <stdio.h>
    
    #include "anet.h"
    
    static void anetSetError(char *err, const char *fmt, ...)
    {
    	va_list ap;
    
    	if (!err) return;
    	va_start(ap, fmt);
    	vsnprintf(err, ANET_ERR_LEN, fmt, ap);
    	va_end(ap);
    }
    
    int anetNonBlock(char *err, int fd)
    {
    	int flags;
    
    	/* Set the socket nonblocking.
    	* Note that fcntl(2) for F_GETFL and F_SETFL can't be
    	* interrupted by a signal. */
    	if ((flags = fcntl(fd, F_GETFL)) == -1) {
    		anetSetError(err, "fcntl(F_GETFL): %s", strerror(errno));
    		return ANET_ERR;
    	}
    	if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
    		anetSetError(err, "fcntl(F_SETFL,O_NONBLOCK): %s", strerror(errno));
    		return ANET_ERR;
    	}
    	return ANET_OK;
    }
    
    int anetTcpNoDelay(char *err, int fd)
    {
    	int yes = 1;
    	if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1)
    	{
    		anetSetError(err, "setsockopt TCP_NODELAY: %s", strerror(errno));
    		return ANET_ERR;
    	}
    	return ANET_OK;
    }
    
    int anetSetSendBuffer(char *err, int fd, int buffsize)
    {
    	if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buffsize, sizeof(buffsize)) == -1)
    	{
    		anetSetError(err, "setsockopt SO_SNDBUF: %s", strerror(errno));
    		return ANET_ERR;
    	}
    	return ANET_OK;
    }
    
    int anetTcpKeepAlive(char *err, int fd)
    {
    	int yes = 1;
    	if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) == -1) {
    		anetSetError(err, "setsockopt SO_KEEPALIVE: %s", strerror(errno));
    		return ANET_ERR;
    	}
    	return ANET_OK;
    }
    
    int anetResolve(char *err, char *host, char *ipbuf)
    {
    	struct sockaddr_in sa;
    
    	sa.sin_family = AF_INET;
    	if (inet_aton(host, &sa.sin_addr) == 0) {
    		struct hostent *he;
    
    		he = gethostbyname(host);
    		if (he == NULL) {
    			anetSetError(err, "can't resolve: %s", host);
    			return ANET_ERR;
    		}
    		memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
    	}
    	strcpy(ipbuf,inet_ntoa(sa.sin_addr));
    	return ANET_OK;
    }
    
    static int anetCreateSocket(char *err, int domain) {
    	int s, on = 1;
    	if ((s = socket(domain, SOCK_STREAM, 0)) == -1) {
    		anetSetError(err, "creating socket: %s", strerror(errno));
    		return ANET_ERR;
    	}
    
    	/* Make sure connection-intensive things like the redis benckmark
    	* will be able to close/open sockets a zillion of times */
    	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
    		anetSetError(err, "setsockopt SO_REUSEADDR: %s", strerror(errno));
    		return ANET_ERR;
    	}
    	return s;
    }
    
    #define ANET_CONNECT_NONE 0
    #define ANET_CONNECT_NONBLOCK 1
    static int anetTcpGenericConnect(char *err, char *addr, int port, int flags)
    {
    	int s;
    	struct sockaddr_in sa;
    
    	if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
    		return ANET_ERR;
    
    	sa.sin_family = AF_INET;
    	sa.sin_port = htons(port);
    	if (inet_aton(addr, &sa.sin_addr) == 0) {
    		struct hostent *he;
    
    		he = gethostbyname(addr);
    		if (he == NULL) {
    			anetSetError(err, "can't resolve: %s", addr);
    			close(s);
    			return ANET_ERR;
    		}
    		memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
    	}
    	if (flags & ANET_CONNECT_NONBLOCK) {
    		if (anetNonBlock(err,s) != ANET_OK)
    			return ANET_ERR;
    	}
    	if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
    		if (errno == EINPROGRESS &&
    			flags & ANET_CONNECT_NONBLOCK)
    			return s;
    
    		anetSetError(err, "connect: %s", strerror(errno));
    		close(s);
    		return ANET_ERR;
    	}
    	return s;
    }
    
    int anetTcpConnect(char *err, char *addr, int port)
    {
    	return anetTcpGenericConnect(err,addr,port,ANET_CONNECT_NONE);
    }
    
    int anetTcpNonBlockConnect(char *err, char *addr, int port)
    {
    	return anetTcpGenericConnect(err,addr,port,ANET_CONNECT_NONBLOCK);
    }
    
    int anetUnixGenericConnect(char *err, char *path, int flags)
    {
    	int s;
    	struct sockaddr_un sa;
    
    	if ((s = anetCreateSocket(err,AF_LOCAL)) == ANET_ERR)
    		return ANET_ERR;
    
    	sa.sun_family = AF_LOCAL;
    	strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
    	if (flags & ANET_CONNECT_NONBLOCK) {
    		if (anetNonBlock(err,s) != ANET_OK)
    			return ANET_ERR;
    	}
    	if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) == -1) {
    		if (errno == EINPROGRESS &&
    			flags & ANET_CONNECT_NONBLOCK)
    			return s;
    
    		anetSetError(err, "connect: %s", strerror(errno));
    		close(s);
    		return ANET_ERR;
    	}
    	return s;
    }
    
    int anetUnixConnect(char *err, char *path)
    {
    	return anetUnixGenericConnect(err,path,ANET_CONNECT_NONE);
    }
    
    int anetUnixNonBlockConnect(char *err, char *path)
    {
    	return anetUnixGenericConnect(err,path,ANET_CONNECT_NONBLOCK);
    }
    
    /* Like read(2) but make sure 'count' is read before to return
    * (unless error or EOF condition is encountered) */
    int anetRead(int fd, char *buf, int count)
    {
    	int nread, totlen = 0;
    	while(totlen != count) {
    		nread = read(fd,buf,count-totlen);
    		if (nread == 0) return totlen;
    		if (nread == -1) return -1;
    		totlen += nread;
    		buf += nread;
    	}
    	return totlen;
    }
    
    /* Like write(2) but make sure 'count' is read before to return
    * (unless error is encountered) */
    int anetWrite(int fd, char *buf, int count)
    {
    	int nwritten, totlen = 0;
    	while(totlen != count) {
    		nwritten = write(fd,buf,count-totlen);
    		if (nwritten == 0) return totlen;
    		if (nwritten == -1) return -1;
    		totlen += nwritten;
    		buf += nwritten;
    	}
    	return totlen;
    }
    
    static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len) {
    	if (bind(s,sa,len) == -1) {
    		anetSetError(err, "bind: %s", strerror(errno));
    		close(s);
    		return ANET_ERR;
    	}
    
    	/* Use a backlog of 512 entries. We pass 511 to the listen() call because
    	* the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
    	* which will thus give us a backlog of 512 entries */
    	if (listen(s, 511) == -1) {
    		anetSetError(err, "listen: %s", strerror(errno));
    		close(s);
    		return ANET_ERR;
    	}
    	return ANET_OK;
    }
    
    int anetTcpServer(char *err, int port, char *bindaddr)
    {
    	int s;
    	struct sockaddr_in sa;
    
    	if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
    		return ANET_ERR;
    
    	memset(&sa,0,sizeof(sa));
    	sa.sin_family = AF_INET;
    	sa.sin_port = htons(port);
    	sa.sin_addr.s_addr = htonl(INADDR_ANY);
    	if (bindaddr && inet_aton(bindaddr, &sa.sin_addr) == 0) {
    		anetSetError(err, "invalid bind address");
    		close(s);
    		return ANET_ERR;
    	}
    	if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa)) == ANET_ERR)
    		return ANET_ERR;
    	return s;
    }
    
    int anetUnixServer(char *err, char *path, mode_t perm)
    {
    	int s;
    	struct sockaddr_un sa;
    
    	if ((s = anetCreateSocket(err,AF_LOCAL)) == ANET_ERR)
    		return ANET_ERR;
    
    	memset(&sa,0,sizeof(sa));
    	sa.sun_family = AF_LOCAL;
    	strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
    	if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa)) == ANET_ERR)
    		return ANET_ERR;
    	if (perm)
    		chmod(sa.sun_path, perm);
    	return s;
    }
    
    static int anetGenericAccept(char *err, int s, struct sockaddr *sa, socklen_t *len) {
    	int fd;
    	while(1) {
    		fd = accept(s,sa,len);
    		if (fd == -1) {
    			if (errno == EINTR)
    				continue;
    			else {
    				anetSetError(err, "accept: %s", strerror(errno));
    				return ANET_ERR;
    			}
    		}
    		break;
    	}
    	return fd;
    }
    
    int anetTcpAccept(char *err, int s, char *ip, int *port) {
    	int fd;
    	struct sockaddr_in sa;
    	socklen_t salen = sizeof(sa);
    	if ((fd = anetGenericAccept(err,s,(struct sockaddr*)&sa,&salen)) == ANET_ERR)
    		return ANET_ERR;
    
    	if (ip) strcpy(ip,inet_ntoa(sa.sin_addr));
    	if (port) *port = ntohs(sa.sin_port);
    	return fd;
    }
    
    int anetUnixAccept(char *err, int s) {
    	int fd;
    	struct sockaddr_un sa;
    	socklen_t salen = sizeof(sa);
    	if ((fd = anetGenericAccept(err,s,(struct sockaddr*)&sa,&salen)) == ANET_ERR)
    		return ANET_ERR;
    
    	return fd;
    }
    
    int anetPeerToString(int fd, char *ip, int *port) {
    	struct sockaddr_in sa;
    	socklen_t salen = sizeof(sa);
    
    	if (getpeername(fd,(struct sockaddr*)&sa,&salen) == -1) {
    		*port = 0;
    		ip[0] = '?';
    		ip[1] = '\0';
    		return -1;
    	}
    	if (ip) strcpy(ip,inet_ntoa(sa.sin_addr));
    	if (port) *port = ntohs(sa.sin_port);
    	return 0;
    }
    
    int anetSockName(int fd, char *ip, int *port) {
    	struct sockaddr_in sa;
    	socklen_t salen = sizeof(sa);
    
    	if (getsockname(fd,(struct sockaddr*)&sa,&salen) == -1) {
    		*port = 0;
    		ip[0] = '?';
    		ip[1] = '\0';
    		return -1;
    	}
    	if (ip) strcpy(ip,inet_ntoa(sa.sin_addr));
    	if (port) *port = ntohs(sa.sin_port);
    	return 0;
    }
    

    #include <stdio.h>
    #include <errno.h>
    #include <signal.h>
    #include "ae.h"
    #include "anet.h"
    
    #define PORT 4444
    #define MAX_LEN 1024
    
    //存放错误信息的字符串
    char g_err_string[1024];
    
    //事件循环机制
    aeEventLoop *g_event_loop = NULL;
    
    //定时器的入口,输出一句话
    int PrintTimer(struct aeEventLoop *eventLoop, long long id, void *clientData)
    {
    	static int i = 0;
    	printf("Test Output: %d\n", i++);
    	//10秒后再次执行该函数
    	return 10000;
    }
    
    //停止事件循环
    void StopServer()
    {
    	aeStop(g_event_loop);
    }
    
    void ClientClose(aeEventLoop *el, int fd, int err)
    {
    	//如果err为0,则说明是正常退出,否则就是异常退出
    	if( 0 == err )
    		printf("Client quit: %d\n", fd);
    	else if( -1 == err )
    		fprintf(stderr, "Client Error: %s\n", strerror(errno));
    
    	//删除结点,关闭文件
    	aeDeleteFileEvent(el, fd, AE_READABLE);
    	close(fd);
    }
    
    //有数据传过来了,读取数据
    void ReadFromClient(aeEventLoop *el, int fd, void *privdata, int mask)
    {
    	char buffer[MAX_LEN] = { 0 };
    	int res;
    	res = read(fd, buffer, MAX_LEN);
    	if( res <= 0 )
    	{
    		ClientClose(el, fd, res);
    	}
    	else
    	{
    		res = write(fd, buffer, MAX_LEN);
    		if( -1 == res )
    			ClientClose(el, fd, res);
    	}
    }
    
    //接受新连接
    void AcceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask)
    {
    	int cfd, cport;
    	char ip_addr[128] = { 0 };
    	cfd = anetTcpAccept(g_err_string, fd, ip_addr, &cport);
    	printf("Connected from %s:%d\n", ip_addr, cport);
    
    	if( aeCreateFileEvent(el, cfd, AE_READABLE,
    		ReadFromClient, NULL) == AE_ERR )
    	{
    		fprintf(stderr, "client connect fail: %d\n", fd);
    		close(fd);
    	}
    }
    
    int main()
    {
    
    	printf("Start\n");
    
    	signal(SIGINT, StopServer);
    
    	//初始化网络事件循环
    	g_event_loop = aeCreateEventLoop(1024*10);
    
    	//设置监听事件
    	int fd = anetTcpServer(g_err_string, PORT, NULL);
    	if( ANET_ERR == fd )
    		fprintf(stderr, "Open port %d error: %s\n", PORT, g_err_string);
    	if( aeCreateFileEvent(g_event_loop, fd, AE_READABLE, 
    		AcceptTcpHandler, NULL) == AE_ERR )
    		fprintf(stderr, "Unrecoverable error creating server.ipfd file event.");
    
    	//设置定时事件
    	aeCreateTimeEvent(g_event_loop, 1, PrintTimer, NULL, NULL);
    
    	//开启事件循环
    	aeMain(g_event_loop);
    
    	//删除事件循环
    	aeDeleteEventLoop(g_event_loop);
    
    	printf("End\n");
    	return 0;
    }

     
    


    展开全文
  • android4.4 系统时间同步,添加NTP备份地址功能

    添加NTP备份地址功能,同步cn.pool.ntp.org服务器时间失败的话,可同步129.6.15.28服务器的时间,双保险。


    diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
    index 81b388d..ae3e286 100644
    --- a/core/java/android/provider/Settings.java
    +++ b/core/java/android/provider/Settings.java
    @@ -2867,6 +2867,7 @@ public final class Settings {
                 MOVED_TO_GLOBAL.add(Settings.Global.NITZ_UPDATE_SPACING);
                 MOVED_TO_GLOBAL.add(Settings.Global.NTP_SERVER);
                 MOVED_TO_GLOBAL.add(Settings.Global.NTP_TIMEOUT);
    +			MOVED_TO_GLOBAL.add(Settings.Global.NTP_BACKUP_SERVER);
                 MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_ERROR_POLL_COUNT);
                 MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS);
                 MOVED_TO_GLOBAL.add(Settings.Global.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT);
    @@ -5074,6 +5075,8 @@ public final class Settings {
     
            /** Preferred NTP server. {@hide} */
            public static final String NTP_SERVER = "ntp_server";
    +       /** Preferred NTP backup server. {@hide} */
    +       public static final String NTP_BACKUP_SERVER = "ntp_server2";
            /** Timeout in milliseconds to wait for NTP server. {@hide} */
            public static final String NTP_TIMEOUT = "ntp_timeout";
     
    diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
    index 602a68c..d1bd18c 100644
    --- a/core/java/android/util/NtpTrustedTime.java
    +++ b/core/java/android/util/NtpTrustedTime.java
    @@ -38,6 +38,9 @@ public class NtpTrustedTime implements TrustedTime {
         private final String mServer;
         private final long mTimeout;
     
    +	private String mBackupServer = null;
    +
         private boolean mHasCache;
         private long mCachedNtpTime;
         private long mCachedNtpElapsedRealtime;
    @@ -49,6 +52,11 @@ public class NtpTrustedTime implements TrustedTime {
             mTimeout = timeout;
         }
     
    +	private void setBackupServer(String server)
    +	{
    +		mBackupServer = server;
    +	}
    +
         public static synchronized NtpTrustedTime getInstance(Context context) {
             if (sSingleton == null) {
                 final Resources res = context.getResources();
    @@ -56,6 +64,8 @@ public class NtpTrustedTime implements TrustedTime {
     
                 final String defaultServer = res.getString(
                         com.android.internal.R.string.config_ntpServer);
    +            final String defaultServer2 = res.getString(
    +                    com.android.internal.R.string.config_ntpServer2);
                 final long defaultTimeout = res.getInteger(
                         com.android.internal.R.integer.config_ntpTimeout);
     
    @@ -64,8 +74,16 @@ public class NtpTrustedTime implements TrustedTime {
                 final long timeout = Settings.Global.getLong(
                         resolver, Settings.Global.NTP_TIMEOUT, defaultTimeout);
     
    +			final String secureServer2 = Settings.Global.getString(
    +                    resolver, Settings.Global.NTP_BACKUP_SERVER);
    +
                 final String server = secureServer != null ? secureServer : defaultServer;
    +            final String backupServer = secureServer2 != null ? secureServer2 : defaultServer2;
                 sSingleton = new NtpTrustedTime(server, timeout);
    +			if(sSingleton != null)
    +			{
    +				sSingleton.setBackupServer(backupServer);
    +			}
             }
     
             return sSingleton;
    @@ -80,7 +98,8 @@ public class NtpTrustedTime implements TrustedTime {
     
             if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
             final SntpClient client = new SntpClient();
    -        if (client.requestTime(mServer, (int) mTimeout)) {
    +        if (client.requestTime(mServer, (int) mTimeout) ||
    +			(mBackupServer != null && client.requestTime(mBackupServer, (int) mTimeout))) {
                 mHasCache = true;
                 mCachedNtpTime = client.getNtpTime();
                 mCachedNtpElapsedRealtime = client.getNtpTimeReference();
    diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
    index b7dd977..88550e1 100644
    --- a/core/res/res/values/config.xml
    +++ b/core/res/res/values/config.xml
    @@ -1060,7 +1060,9 @@
         <bool name="config_allowActionMenuItemTextWithIcon">false</bool>
     
         <!-- Remote server that can provide NTP responses. -->
    -    <string translatable="false" name="config_ntpServer">2.android.pool.ntp.org</string>
    +    <string translatable="false" name="config_ntpServer">cn.pool.ntp.org</string>
    +    <!-- Remote server that can provide NTP backup responses. -->
    +    <string translatable="false" name="config_ntpServer2">129.6.15.28</string>
         <!-- Normal polling frequency in milliseconds -->
         <integer name="config_ntpPollingInterval">864000000</integer>
         <!-- Try-again polling interval in milliseconds, in case the network request failed -->
    diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
    index 84e6cce..957a821 100755
    --- a/core/res/res/values/symbols.xml
    +++ b/core/res/res/values/symbols.xml
    @@ -477,6 +477,7 @@
       <java-symbol type="string" name="config_mms_user_agent" />
       <java-symbol type="string" name="config_mms_user_agent_profile_url" />
       <java-symbol type="string" name="config_ntpServer" />
    +  <java-symbol type="string" name="config_ntpServer2" />
       <java-symbol type="string" name="config_tether_apndata" />
       <java-symbol type="string" name="config_useragentprofile_url" />
       <java-symbol type="string" name="config_wifi_p2p_device_type" />
    
    diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
    index 316440f..b46b632 100644
    --- a/core/java/android/net/SntpClient.java
    +++ b/core/java/android/net/SntpClient.java
    @@ -120,7 +120,7 @@ public class SntpClient
                 mNtpTimeReference = responseTicks;
                 mRoundTripTime = roundTripTime;
             } catch (Exception e) {
    -            if (false) Log.d(TAG, "request time failed: " + e);
    +            if (/*false*/true) Log.d(TAG, "request time failed: " + e);
                 return false;
             } finally {
                 if (socket != null) {
    


    展开全文
  • Sketch2AE for Mac 破解版是一款Sketch文件资源导入AE插件,成功解决Sketch导入AE不兼容的问题。Sketch2AE插件可以轻松导出 Sketch 资源至 Adobe After Effects 并自动定位,需要的朋友快来下载试试吧! 原文及下载...

    Sketch2AE for Mac 破解版是一款Sketch文件资源导入AE插件,成功解决Sketch导入AE不兼容的问题。Sketch2AE插件可以轻松导出 Sketch 资源至 Adobe After Effects 并自动定位,需要的朋友快来下载试试吧!

    原文及下载地址:http://mac.orsoon.com/Mac/167758.html

     

    Sketch文件导入AE插件 Sketch2AE for Mac 破解版 官方介绍

    现在可以将Sketch图层导入After Effects,而无需重新绘制Illustrator中的所有内容。避免令人吃惊的认识,即您必须重复整个导入过程,因为您忘记将一个元素拆分到其自己的图层上,或者该类型必须转换为实时文本作为每层的附加过程。

    从Sketch中快速导出所选图层或整个画板,其中包括类型度量,转换数据,图像,符号层次结构和完整分组。它比原生Illustrator => AE导入要好一点。万岁。

    Sketch文件导入AE插件 Sketch2AE for Mac 破解版 插件功能

    解决方法

    图像渲染和位置偏移

    模糊颜色调整 等图像效果将与导出的图像一起渲染,以在Sketch中保留其设计。有时,这些效果可以增加一个大于指标的层的界限。这导致层的位置偏移,将其向下推向右侧。AE中需要进行一些手动调整才能纠正此问题。

    渲染图像上的粗笔划(使用渐变和纹理)也会导致此位置偏移 - 需要注意的事项。

    文字错位

    它发生了。对于那个很抱歉。对Sketch和AE之间的差异进行排序的数学不能捕捉所有内容(尤其是多行文本字符串)。好消息是文本是实时的,可以轻松编辑和重新排列。

    形状旋转

    由于Sketch没有锚点的概念,因此形状旋转完全基于对象中心。这意味着形状旋转可以支持并保持精确定位。图层>组合>展平所有路径以确保正确导入。

    Sketch文件导入AE插件 Sketch2AE for Mac 破解版 插件特征

    AE中的Sketch特征

    分组

    群组不是AE内部的东西,但它们确实应该是。为了支持元素分组,Sketch2AE将创建一个边界框图层作为分组图层的父级。此父层将处于非活动状态并设置为害羞以防止comp混乱。手动激活这些图层(单击眼球),或单击“ 组可见性”按钮以切换所有这些分组图层。
     

    符号

    最强大的Sketch功能之一是Symbols。元素可以存在于多个位置和画板中,并指向单个参考以便快速更新。嗯......这听起来很像precomp。Sketch Symbols将以其原始大小创建为precomps,根据需要进行缩放并在master comps中重用。
     

    渐变作为图像

    我们已经非常谨慎地导入尽可能多的可编辑(和可动画)属性。AE不能很好地导入的一个属性是渐变(渐变编辑面板不可编写脚本)。为了解决这个问题,Sketch2AE将导出渐变填充,渐变笔划,图像填充和纹理作为图层的图像。
     

    Sketch文件导入AE插件 Sketch2AE for Mac 破解版 使用方法

    1.复制到新的Sketch文件

    选择您的画板,创建一个新的Sketch文件,将画板粘贴到新文件中。

    **此步骤是可选的,但建议使用。**
    为什么?Sketch文件中的复杂性因用户而异。为了找到文件中的所有符号,插件必须遍历所有符号才能找到正确的符号。这可能需要很长时间来自贴纸或类似的重文件。
     

    2.设置画板

    在Sketch内部,资产可以在没有Artboard的情况下在文件中浮动(就像贴纸一样)。这对于在Sketch中工作来说非常酷,但为了让Sketch2AE知道在AE comp中绘制所有内容有多大,我们需要一个画板。画板的大小将是comp的范围,因此请正确设置此大小。Sketch中的

    键盘快捷键A允许您根据需要定义新画板。
     

    3.选择图层

    在画板中的所有艺术品上拖动边界框以选择所有可见图层,或选择要导出的特定图层。选择这种方式将跳过可能仅存在于画板中以供参考的不可见层。

    或选择画板本身以选择所有图层(隐藏或可见)。
     

    4. Sketch2AE出口

    • 复制选定的图层
      创建所有选定图层数据的列表,并将其复制到剪贴板以减少额外的文件*。
    • 保存选定的图层
      将所有选定图层数据的列表保存到文件中:_SketchExport.Sketchae。在没有草图的情况下切换到After Effects用户很有帮助。
    * 将导出所选图层中的图像(以及渐变)以导入After Effects。
     

    5.导入AE

    随着Sketch2AE板打开时,选择的两个导入选项中的一个将数据从草图或打开粘贴和导出 .Sketchae文件。将导入图像(如果适用),符号将构建为可重复使用的预编译(如果适用),并将根据导入选项构建大量图层。
     

    6.导入选项

    草图中的数据将通过几个简单的选项导入。
    • 可以为1x,2x或3x的每次导入创建新的comp。
    • 数据也可以添加到open comp中。导入的画板(和所有图层)将缩放以适合水平打开的comp。

    更新日志

    Sketch文件导入AE插件 Sketch2AE for Mac v0.54破解版

    修复

    • 自Sketch 49发布以来,该插件已被破坏。

    Sketch文件导入AE插件 Sketch2AE for Mac 破解版 安装教程

    Sketch文件导入AE插件 Sketch2AE for Mac 破解版镜像包下载完成后打开,先打开Sketch软件,再双击打开【Sketch2AE.sketchplugin】

    提示Sketch2AE插件安装完成。

    在菜单栏插件一栏下我们看到Sketch2AE插件已经安装好了。

    然后将【Sketch2AE.jsx】拷贝到【ScriptUI Panels】(/Applications/Adobe After Effects<版本号>/Scripts/ScriptUI Panels)

    重启ae软件,要使用该AE脚本插件,需要在 After Effects 中打开 After Effects - 首选项 - 常规 ,勾选 允许脚本写入文件和访问网络,点击确定。

    然后在窗口一栏就能找到安装好的Sketch2AE插件了。

    展开全文
  • 时间轴变换功能 画一个圆形,中心点不在圆上,选择锚点工具按住Ctrl键移动中心点到圆上面就会自动变成圆的中心点,按Alt键点击中心点,中心点不会移动,圆会移动 ...手动添加关键帧:把时间指示器移动
  • AE开发集锦

    千次阅读 2014-07-21 18:05:13
    用ArcEngine的工具条添加图层要素... 2 3.  ArcEngine中对Feature的编辑... 5 4.  Feature的概念... 6 5.  如何实现经度纬度到平面坐标的相互转换?(转载)... 7 6.  ArcEngine 最短路径分析(源码)......
  • 【模板信息】:创意分屏旋转七彩百叶广告片头模版,是一款将图片添加各种效果展现出来的AE模版。 【时间长度】:1分09秒 【版本要求】:建议使用(CS6-CC 2015)英文版本打开 【插件要求】:无需第三方插件 【模板...
  • AE操作常见问题

    千次阅读 2014-12-17 20:37:10
    Q:AE中如何输出单帧图片? A:Ctrl+Alt+S Q:MASK如何等比例缩放? A:Ctrl+Alt+拖动鼠标 Q:AE中为何不能导入序列文件? A:可能是中文目录也可能是文件名不对 Q:VCD中的DAT文件无法导入AE怎么办? A:把把*.DAT,...
  • mac AE 快捷键

    千次阅读 2019-10-04 22:34:20
    项目窗口 新项目Ctrl+Alt+N 打开项目Ctrl+O 打开项目时只打开项目窗口 按住Shift键 打开上次打开的...双击 在AE素材窗口中打开影片Alt+双击 激活最近激活的合成图像 增加选择的子项到最近激活的合成图像中...
  • Project -》Add to Project 插入 Microsoft Date and Time Picker Control 控件...下面是参考的 http://topic.csdn.net/u/20080315/12/AE6C4745-AF7B-4BBD-AA9F-D6F299DA2367.htmlExamplevoid CDatesDlg::OnButton2()
  • 此插件可以将3DMAX软件中的摄像机信息导入到AE当中, 然后在AE添加我们想要的任何元素,而且有三维信息, 大大节省了摄像机匹配的时间,让制作更加简单。
  • 新手的话不太建议在这方面花太多时间,因为表达式是个难点,但在AE中并算不上重点,不会表达式KK帧很多效果都能搞定。 第一步:开启表达式 首先我们来说说如何开启表达式和表达式的一些功能按键。首先,如何开启表
  • 上图有【品质】按钮。 下图无【品质】按钮。 解决方法步骤: 1、点击 展开或折叠“图层开关”窗格 按钮(就是最左下角的那个) 2、就可以看到【品质】按钮了。
  • AE属性表操作

    万次阅读 2015-02-07 10:27:39
    接着在toc右键事件中添加代码:   [csharp]   view plain copy //查看属性表    m_menuLayer.AddItem( new  OpenAttribute(mapMain), -1, 2,  false , ...
  • AE简单粒子特效动画制作

    千次阅读 2018-08-02 10:32:35
    第一步:在ae软件里新建一个合成CTRL+N时间设置为10s之内都行,接下来再新建一个图层(图层底色最好跟合成颜色一致。)CTRL+Y。 第二步:在任务栏里找到效果,点击里面的Trapcode里的粒子插件Particular添加到纯色...
  • AE常用表达式详解

    千次阅读 2020-09-30 18:37:53
    1.全局对象、属性和方法(Global) comp(name) ——返回类型:合成。按照名称检索其他合成。 footage(name) ——返回类型:素材。... 表示以秒为单位的合成时间,将以此计算表达式。 2.矢量数学方法(Vector Mat
  • 如何用ae制作文字破碎效果

    千次阅读 2019-09-25 17:09:21
    今天给大家带来了ae教程:用ae制作文字破碎效果。 那就直接开始吧,具体步骤如下: 1、新建一个合成,选择自己想要的大小并命名。 (快捷键:Ctrl + N ) 2、新建一个纯色图层用作背景。 (因为在新建合成的时候...
  • 详解自动编码器(AE)

    千次阅读 多人点赞 2019-11-21 11:57:34
    自动编码器(Auto-Encoders,AE) 降噪自编码(Denoising Auto-Encoders, DAE)(2008) 堆叠降燥自动编码器 (Stacked Denoising Auto-Encoders, SAE)(2008) 卷积自动编码器(Convolution Auto-Encoders, CAE)(2011) 变分...
  • AE图层叠加模式

    千次阅读 2019-03-05 13:22:30
    时间线上,通过按下时间线窗口左下角不同的层展开/折叠开关按钮,可以展开层控制和层模式面板,按下快捷键F4,时间线窗口会在层面板和层模式面板之间进行切换,在层模式面板Mode栏中可以选择不同的层叠加方式: ...
  • 插件为AE带来了额外的功能,每一个动态设计师在日常工作中都会有一些依赖的插件。不管你是高手还是菜鸟,下面这7款插件都会让你的功力突飞猛进,来看有哪款适合你的! 1、Trapcode Particulars Trapcode Particular...
  • AE常用快捷键及最常用功能说明

    千次阅读 2019-02-25 21:23:17
    AE中,单就功能操作而言,总体包括两个方面,那就是图层和特效(ctrl+5打开特效预设面板)。特效部分那就需要根据具体的特效插件来分述,但以图层操作为中心的功能相对来说是比较有限的,最关键的是,如果如果有关...
  • AE CS5开始就取消了直接输出GIF动图的功能 AE输出GIF动图格式的方法需要外部插件 已经内置破解,安装即可直接使用:GifGun AE输出GIF动图脚本插件安装教程 1、安装之前,用户请确保本机已经安装下列AE(After ...
  • CNN,GAN,AE和VAE概述

    千次阅读 2019-01-13 10:38:16
    然后,我们将使用multiple多个元素,并使用add添加元素。这使得网络可以改变正态分布的方差。这就是它编码信息的方式。在对元素进行加法和乘法运算之后,我们就得到了一个潜在向量。我们将这个潜在向量输入输出层,...
  • ae教程(二)文字类

    千次阅读 2018-07-28 13:36:34
    在视频制作过程中少不了一些...首先普及一下,其实ae自带了很多效果动画完全可以满足我们的基本需求          点击将动画预设应用于 选择文件夹 选择想要的动画效果  今天我们主要讲的是文字动画所以我...
  • AE中网络分析的实现

    千次阅读 2013-05-08 21:00:54
    在网络的属性中,可以添加成本、等级和限制等属性。成本用于累积计算最短路径(一般为距离和时间);等级用于道路等级的划分(使用等级执行网络分析时,将应用启发式算法,该算法在选择道路时倾向于更高级别的等级)...
  • TypeMonkey for Mac是一款安装After Effects中使用的AE文字排列效果脚本插件,AE文本复杂排列动画脚本 TypeMonkey适用于各类视频,ae脚本typemonkey主要用来创建排列文字效果,可以将歌词或文字混排输入,赶紧试试ae...
  • AE入门案例——制作新闻联播片头

    千次阅读 2019-11-10 11:15:39
    AE软件,一般学校官网有正版免费软件下载。 一张世界地图。 实现过程 导入素材图片。 可以单击菜单栏:文件→导入;也可以将图片直接拖入导入。 将导入的图片拖入合成合成窗口。 导入球形效果 点击...
  • BAO Bones Mac 激活版是一款AE角色骨骼IK绑定动画插件,帮助您在AE上建立骨骼模型,将骨骼添加到动画上更加轻松,不需要借助复杂的AE建模功能以及渲染功能就可以设计出完美的模型;AE角色骨骼IK绑定动画插件使用的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 43,944
精华内容 17,577
关键字:

ae添加时间