1.SRS(simple-rtmp-server)流媒体服务器源码分析--RTMP消息play
2.跟着文章读一篇,源码人人都能了解Vue3 系列(一)(从0构建pnpm项目,源码 跑通内部渲染流程)
3.Simple PHP Blog详情
4.å¦ä½èªå·±å®ç°ä¸ä¸ªç®åçArrayList
5.simplecd简介
6.推荐!ant-simple-pro2.0正式发布,源码助力vue3社区
SRS(simple-rtmp-server)流媒体服务器源码分析--RTMP消息play
本章内容梳理了SRS在接收到RTMP信息后如何进行转发的源码过程。在此过程中,源码首先进行代码梳理,源码怪物x联盟游戏源码作者也在源码熟悉阶段,源码可能尚未完全梳理完接受到RTMP后信息如何处理、源码缓存以及转发给直播用户等内容。源码
SRS源码中的源码Play流程如下:
1. 进入play流程:本章内容直接从SrsRtmpConn::stream_service_cycle()方法开始梳理。
2. 在接受流程中,源码客户类型为SrsRtmpConnFMLEPublish “fmle publish”,源码而在转发流程中,源码客户类型为SrsRtmpConnPlay。源码
3. 在http_hooks_on_play()方法中,源码回调on_play()方法通知vhost,xxx用户已经开始play。
4. 在http_hooks_on_stop()方法中,回调on_stop()方法通知vhost,xxx用户已经停止play。
5. 最重要的是进入该函数。
在函数中:
1.1 根据客户端创建消费者对象:create_consumer(this,c winform erp源码 consumer)
1.2 为该消费者开启一个独立协程:trd.start() //此处一直不太明白,在play流程中创建一个协程用来做什么?
1.3 进入play主流程:do_playing(source, consumer, &trd);
2. 进入主play循环:do_playing()函数内容众多且非常重要,因此将函数内容全部列出。
2.1 通知消费者准备play
2.2 从消费者列表中取出Rtmp信息(SrsMessageQueue)
2.3 进入play入口
3. 进入SRS发送接口(play):在int SrsProtocol::send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, int stream_id)函数中,进入int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs),该函数有一个#ifdef SRS_PERF_COMPLEX_SEND宏定义,一般rtmp协议都是要混合音视频数据,在做转发。在往后面看,
最后进入
在该函数中,最重要的一点是send message总出口writen()函数。它负责将转发给直播用户的流转发出去。
4. 最后:play总结
(1)通知client开始play
(2)从消费者列表中取出Rtmp数据
(3)从总出口writev()函数中转发出去
跟着文章读一篇,人人都能了解Vue3 系列(一)(从0构建pnpm项目, 跑通内部渲染流程)
让我们开始构建一个简单的Vue3项目,从零开始,重点是pnpm管理和内部渲染流程的实现。首先,创建一个名为"simple-mini-vue3"的新项目,推荐使用pnpm作为依赖管理工具。
在项目结构中,创建一个pnpm-workspace.yaml文件,变身吧主公源码配置工作空间,确保所有源码存储在packages文件夹中,包间相互关联通过workspace协议。同时,添加.shamefully-hoist配置以避免不必要的幽灵依赖问题。详细解释见pnpm官方文档,这里不深入探讨。
在根目录下,新建packages和runtime-core文件夹,进入runtime-core并执行npm init初始化package.json。稍后会逐步解释package.json的配置。此时,项目基本骨架已搭建完成。
我们的目标是使项目运行起来,通过在HTML中引入编写好的JS或TS代码,在浏览器中直接查看效果。为此,我们将使用esbuild进行开发打包。在项目根目录下创建scripts文件夹,用于存放与项目构建相关的脚本,不包含在源码包中。netty 权威指南 源码
在scripts文件夹的dev.js中编写打包脚本,使用浏览器ESM原生支持,实现项目实时编译和预览。在package.json中添加开发运行脚本,以便一键执行打包任务。
通过以上步骤,你将成功搭建并运行一个基于pnpm的Vue3项目,可以直接在浏览器中查看源码编写的实时效果。每个配置和脚本的细节将逐一解析,让你更加深入地理解项目构建流程。
Simple PHP Blog详情
本文介绍的是一个使用PHP编写的简单博客平台,它遵循的是GNU通用公共许可证(GPL)协议,这意味着它的源代码是开放和自由的,用户可以根据需要自由使用和修改。这个平台的设计不依赖于特定的操作系统,无论是在Windows、Mac还是Linux环境下,它都能正常运行。
它支持多种语言,包括中文(简体)和中文(繁体),以及丹麦文、java 分析java源码荷兰文、英语、法文、德文、意大利文、日文、马来文、葡萄牙文、俄文、西班牙语、泰米尔文和土耳其文,为全球用户提供便捷的阅读和发表内容的环境。
这款博客主要面向终端用户和桌面用户,特别是那些需要在Web环境中进行日常信息交流和技术分享的个人或团队。用户接口设计为基于Web的形式,用户可以轻松通过浏览器访问和管理博客内容,无需下载或安装任何额外的软件。
核心技术方面,它采用PHP作为编程语言,这使得开发和维护起来相对简单,且PHP社区丰富,对于遇到的问题,通常能找到充足的解决方案。至于数据存储,这个博客平台采用扁平文件数据库,这意味着数据直接存储在文件中,适合小型或低复杂度的项目,易于管理,但可能不适用于处理大量数据的场景。
å¦ä½èªå·±å®ç°ä¸ä¸ªç®åçArrayList
ArrayListæ¯Javaéåæ¡æ¶ä¸ä¸ä¸ªç»å ¸çå®ç°ç±»ãä»æ¯èµ·å¸¸ç¨çæ°ç»èè¨ï¼ææ¾çä¼ç¹å¨äºï¼å¯ä»¥éæçæ·»å åå é¤å ç´ èä¸éèèæ°ç»ç大å°ãå®ç°ä¸ä¸ªç®åçArrayListï¼å®ç°çè¿ç¨ï¼
å®ç°çArrayList主è¦çåè½å¦ä¸ï¼
é»è®¤æé å¨åä¸ä¸ªåæ°çæåæé å¨
addæ¹æ³
getæ¹æ³
indexOfæ¹æ³
containsæ¹æ³
sizeæ¹æ³
isEmptyæ¹æ³
removeæ¹æ³
è¿ä¸ªç®åçArrayListç±» åå为SimpleArrayListï¼å ¨é¨ç代ç æ¥çSimpleArrayList代ç
æé å¨
æºç ArrayListä¸å ±æä¸ä¸ªæé å¨ï¼ä¸ä¸ªæ åæé å¨ï¼ä¸ä¸ªåæ°ä¸ºintåæåæé å¨ï¼ä¸ä¸ªåæ°ä¸ºCollectionåçæåæé å¨ãåæ°ä¸ºCollectionåçæé å¨ç¨æ¥å®ç°å°å ¶ä»ç»§æ¿Collectionç±»ç容å¨ç±»è½¬æ¢æArrayListãSimpleArrayListç±»å 为è¿æ²¡ææå¨å®ç°å ¶ä»ç容å¨ç±»ï¼æ以å®ç°çæé æ¹æ³åªæ2个ã代ç å¦ä¸ï¼
public SimpleArrayList(){ this(DEFAULT_CAPACITY);} public SimpleArrayList(int size){ if (size < 0){ throw new IllegalArgumentException("é»è®¤ç大å°" + size);
}else{
elementData = new Object[size];
}
}
æ åæé å¨ä¸ç DEFAULT_CAPACITYæ¯å®ä¹çç§æåéï¼é»è®¤å¼æ¯ï¼ç¨æ¥å建ä¸ä¸ªå¤§å°ä¸ºçæ°ç»ãæåæé å¨ä¸ï¼intåæ°æ¯ç¨æ¥çæä¸ä¸ªæå®å¤§å°çObjectæ°ç»ãå°å建好çæ°ç»ä¼ ç»elementDataãelementDataæ¯çæ£çç¨æ¥åå¨å ç´ çæ°ç»ãaddæ¹æ³
add æ¹æ³ç¨æ¥å¾å®¹å¨ä¸æ·»å å ç´ ï¼addæ¹æ³æ两个éè½½æ¹æ³ï¼ä¸ä¸ªæ¯add(E e),å¦ä¸ä¸ªæ¯add(int index, E e)ãaddæ¬èº«å¾ç®åï¼ä½æ¯è¦å¤çå¨ææ°ç»ï¼å³æ°ç»å¤§å°ä¸æ»¡è¶³çæ¶åï¼æ©å¤§æ°ç»çå åãå ·ä½ç代ç å¦ä¸ï¼
public void add(E e){isCapacityEnough(size + 1);
elementData[size++] = e;
}
æ¹æ³isCapacityEnoughå°±æ¯æ¥å¤ææ¯å¦éè¦æ©å®¹ï¼ä¼ å ¥çåæ°å°±æ¯æå°çæ©å®¹ç©ºé´ãå 为addä¸ä¸ªå ç´ ï¼æ以æå°çæ©å®¹ç©ºé´ï¼å³æ°çé¿åº¦æ¯ææå ç´ + 1ãè¿éçsizeå°±æ¯çæ£çå ç´ ä¸ªæ°ã private void isCapacityEnough(int size){ if (size > DEFAULT_CAPACITY){explicitCapacity(size);
} if (size < 0){ throw new OutOfMemoryError();
}
}
å¤ææ©å®¹çæ¹æ³ä¹å¾ç®åï¼å¤æéè¦æ©å®¹ç空é´æ¯ä¸æ¯æ¯é»è®¤ç空é´å¤§ãå¦æéè¦ç空é´æ¯é»è®¤ç空é´å¤§ï¼å°±è°ç¨explicitCapacityè¿è¡æ©å®¹ãè¿éæ个sizeå°äº0çå¤æï¼åºç°sizeå°äº0主è¦æ¯å 为å½sizeè¶ è¿Integer.MAX_VALUEå°±ä¼åæè´æ°ã private final static int MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8; private void explicitCapacity(int capacity){ int newLength = elementData.length * 2; if (newLength - capacity < 0){newLength = capacity;
} if (newLength > (MAX_ARRAY_LENGTH)){
newLength = (capacity > MAX_ARRAY_LENGTH ? Integer.MAX_VALUE : MAX_ARRAY_LENGTH);
}
elementData = Arrays.copyOf(elementData, newLength);
}
ä¸é¢ç代ç æ¯æ©å®¹ç代ç ï¼é¦å ï¼å®ä¹ä¸ä¸ªæ°ç»æ大ç容éç常é为æ大å¼ï¼è¿ä¸ªå¼æç §å®æ¹çæºç ä¸ç解éæ¯è¦æäºVMä¿çäºæ°ç»ç头é¨ä¿¡æ¯å¨æ°ç»ä¸ï¼å æ¤å®é åæ¾æ°æ®ç大å°å°±æ¯æ´æ°çæå¤§å¼ - 8ç¶å设å®ä¸ä¸ªè¦æ©å®¹çæ°ç»ç大å°ï¼è½ç¶ä¸é¢è¯´äºæä¸ä¸ªæ©å®¹ç©ºé´çå¼ size + 1 ï¼è¿ä¸ªæ¯å®é æ们æå°éè¦æ©å®¹ç大å°ãä½ä¸ºäºç»§ç»å¢å å ç´ ï¼èä¸é¢ç¹çæ©å®¹ï¼å æ¤ä¸æ¬¡æ§çç³è¯·å¤ä¸äºçæ©å®¹ç©ºé´ãè¿énewLength æç®ç³è¯·ä¸º æ°ç»é¿åº¦ç2åï¼ç¶åå»å¤æè¿ä¸ªé¿åº¦æ¯å¦æ»¡è¶³éè¦çæ©å®¹ç©ºé´çå¼ã å³æäºåç»ç两段代ç
if (newLength - capacity < 0){ newLength = capacity;} if (newLength > (MAX_ARRAY_LENGTH)){ newLength = (capacity > MAX_ARRAY_LENGTH ? Integer.MAX_VALUE : MAX_ARRAY_LENGTH);
}
å¦æ2åçé¿åº¦ä»ç¶ä¸æ»¡è¶³ï¼åç³è¯·å°éè¦çæ©å®¹é¿åº¦ãå¨æ们åªå¢å ä¸ä¸ªå ç´ çæ åµä¸ï¼è¿ä¸ªå¤ææ¯æ°¸è¿ä¸ä¼çæçï¼ä½æ¯å¦ææaddAllæ¹æ³ï¼åå¢å çå ç´ å¾å¤ï¼å°±è¦å¯¼è´ä¸æ¬¡ç³è¯·2åçé¿åº¦æ¯ä¸å¤çã第äºä¸ªå¤ææ¯å¤ænewLengthçé¿åº¦å¦æè¶ è¿ä¸é¢å®ä¹çæ°ç»æ大é¿åº¦åå¤æè¦éè¦çæ©å®¹ç©ºé´æ¯å¦å¤§äºæ°ç»æ大é¿åº¦ï¼å¦æ大äºånewLength为 MAX_VALUE ï¼å¦å为 MAX_ARRAY_LENGTHãæåï¼çæ£å®ç°æ°ç»æ©å®¹å°è®¾å®é¿åº¦çæ¹æ³å°±æ²¡ææäºï¼è°ç¨Arrays.copyOf(elementData, newLength)å¾å°ä¸ä¸ªæ©å®¹åçæ°ç»ã
addçå¦ä¸ä¸ªéè½½æ¹æ³ä¹å¾ç®åã
public void add(int index, E e) {//å¤ææ¯ä¸æ¯è¶ç
checkRangeForAdd(index);
//å¤æéä¸éè¦æ©å®¹
isCapacityEnough(size + 1);
//å°indexçå ç´ å以åçå ç´ åå移ä¸ä½
System.arraycopy(elementData,index,elementData,index + 1,size - index);
//å°indexä¸æ çå¼è®¾ä¸ºe
elementData[index] = e; size++;
}
private void checkRangeForAdd(int index){ //è¿éindex = sizeæ¯è¢«å 许çï¼å³æ¯æ头ï¼ä¸é´ï¼å°¾é¨æå ¥
if (index < 0 || index > size){ throw new IndexOutOfBoundsException("æå®çindexè¶ è¿çé");
}
}
è³æ¤ï¼ä¸ä¸ªç®åçaddæ¹æ³å°±å®ç°å®äºãgetæ¹æ³
getæ¹æ³ç¨æ¥å¾å°å®¹å¨ä¸æå®ä¸æ çå ç´ ãæ¹æ³å®ç°æ¯è¾ç®åï¼ç´æ¥è¿åæ°ç»ä¸æå®ä¸æ çå ç´ å³å¯ã
private void checkRange(int index) { if (index >= size || index < 0){throw new IndexOutOfBoundsException("æå®çindexè¶ è¿çé");
}
} public E get(int index){
checkRange(index); return (E)elementData[index];
}
indexOfæ¹æ³indexOfæ¹æ³ç¨æ¥å¾å°æå®å ç´ çä¸æ ãå®ç°èµ·æ¥æ¯è¾ç®åï¼éè¦å¤æä¼ å ¥çå ç´ ï¼ä»£ç å¦ä¸ï¼
public int indexOf(Object o){ if (o != null) { for (int i = 0 ; i < size ; i++){ if (elementData[i].equals(o)){ return i;}
}
}else { for (int i = 0 ; i < size ; i++){ if (elementData[i] == null) { return i;
}
}
} return -1;
}
å¤æä¼ å ¥çå ç´ æ¯å¦ä¸ºnullï¼å¦æ为nullï¼åä¾æ¬¡ä¸nullãå¦æä¸ä¸ºç©ºï¼åç¨equalsä¾æ¬¡æ¯è¾ãå¹é æåå°±è¿åä¸æ ï¼å¹é 失败就è¿å-1ãcontainsæ¹æ³
containsç¨æ¥å¤æ该容å¨ä¸æ¯å¦å å«æå®çå ç´ ãå¨æäºindexOfæ¹æ³çåºç¡ä¸ï¼containsçå®ç°å°±å¾ç®åäºã
public boolean contains(Object o){ return indexOf(o) >= 0;}
sizeæ¹æ³sizeæ¹æ³ç¨æ¥å¾å°å®¹å¨ç±»çå ç´ ä¸ªæ°ï¼å®ç°å¾ç®åï¼ç´æ¥è¿åsizeç大å°å³å¯ã
public int size(){ return size;}
isEmptyæ¹æ³isEmptyæ¹æ³ç¨æ¥å¤æ容å¨æ¯å¦ä¸ºç©ºï¼å¤æsizeæ¹æ³çè¿åå¼æ¯å¦ä¸º0å³å¯ã
public boolean isEmpty(){ return size() == 0;}
removeæ¹æ³removeæ¹æ³æ¯ç¨æ¥å¯¹å®¹å¨ç±»çå ç´ è¿è¡å é¤ï¼ä¸addä¸æ ·ï¼removeæ¹æ³ä¹æ两个éè½½æ¹æ³ï¼åå«æ¯
remove(Object o)åremove(int index)
public E remove(int index) {E value = get(index); int moveSize = size - index - 1; if (moveSize > 0){
System.arraycopy(elementData,index + 1, elementData,index,size - index - 1);
}
elementData[--size] = null; return value;
}
public boolean remove(Object o){ if (contains(o)){
remove(indexOf(o)); return true;
}else { return false;
}
}
第ä¸ä¸ªremoveæ¹æ³æ¯æ ¸å¿æ¹æ³ï¼é¦å å¾å°è¦å é¤çä¸æ å ç´ çå¼ï¼ç¶åå¤æindexåé¢çè¦å移çå ç´ ç个æ°ï¼å¦æ个æ°å¤§äºé¶ï¼åè°ç¨åºæ¹æ³ï¼å°indexåé¢çå ç´ åå移ä¸ä½ãæåelementData[--size] = null;缩åsize大å°ï¼å¹¶å°åæåä¸ä½ç½®ç©ºã第äºä¸ªremoveæ¹æ³ä¸éè¦å第ä¸ä¸ªæ¹æ³ä¸æ ·ï¼éè¦åè¯ä½¿ç¨è è¦å é¤çä¸æ 对åºçå ç´ ï¼åªéè¦å¤ææ¯å¦å é¤æåå³å¯ãå¦æè¦å é¤çå ç´ å¨å表ä¸ï¼åå é¤æåï¼å¦æä¸å¨å失败ãå æ¤è°ç¨containsæ¹æ³å°±å¯ä»¥å¤ææ¯å¦è¦å é¤çå ç´ å¨å表ä¸ãå¨åè°ç¨remove(int index),ä¸å¨åè¿å失败ã
simplecd简介
SimpleCD是一个模仿VeryCD功能的全套工具集合,其中包括抓取脚本和网站代码,其主要目标是为VeryCD提供备份服务。它不仅限于备份,还具备基础的搜索和列表管理功能,以满足用户的需求。
SimpleCD是一个开放源代码的网络平台,采用web和Python技术构建。特别值得一提的是,它为Windows个人用户提供了一款桌面版应用,使得用户可以方便地在本地进行操作,无需依赖浏览器。
在BT网站面临关闭和VeryCD调整策略的时期,SimpleCD于年月日诞生,它像一个精神延续,坚守着Emule用户长期以来的分享精神。尽管面临着环境的变迁,SimpleCD仍致力于保持并传递这种自由分享的核心价值。
推荐!ant-simple-pro2.0正式发布,助力vue3社区
推荐一个名为ant-simple-pro的开源项目,它在2月份发布了v1.0版本,并在GitHub上收到了+star。该开源项目提供了一套开箱即用的后台管理模板,能够帮助快速搭建后台管理系统。此外,它支持Vue3、React和Angular,适用于任何框架的管理系统。 在此次版本更新中,React版本的难度不大,但Vue版本的更新则较为复杂。由于Vue3.0某些库与React对应的插件不兼容,我们决定从头开始创建这些库,以确保兼容性和性能。 以下是此次更新中新增的Vue3组件: vue3-grid-layout:借鉴了vue-grid-layout和react-grid-layout,基于vue-grid-layout重写,支持Vue3、TypeScript。 vue3-context-menu:自定义右键菜单组件,支持Vue3、TypeScript。 vue3-qrcode:自定义二维码生成组件,支持Vue3、TypeScript。 vue3-color:借鉴react-color源码,自定义颜色选择器组件,支持Vue3、TypeScript。 vue3-cropImage:上传剪切组件,支持Vue3、TypeScript。 vue3-useHotkeys:按键监听插件,支持Vue3、TypeScript。 vue3-for-editor:Markdown语法编辑器,基于for-editor重写,支持Vue3、TypeScript。 vue3-codemirror:代码编辑器组件,基于CodeMirror重写,支持Vue3、TypeScript。 vue3-tinymce:富文本编辑器组件,基于tinymce和tinymce-vue封装,支持Vue3。 emoji-mart-vue:Emoji表情选择组件,支持Vue3、TypeScript。 项目还包含了许多其他组件和小组件,如上传组件、布局表格、滚动条、SVG组件等。同时,我们还提供了一些Hooks。请访问ant-simple-pro和ant-simple-pro-document文档获取更多信息。 我们是一群初学者开发者,诚邀您指正我们的不足之处,并感谢永豪在Vue版本上的重大贡献。我们承诺将持续更新和迭代项目,确保其得到维护。 如果您对H5游戏、Webpack、Node、Gulp、CSS3、JavaScript、NodeJS、Canvas数据可视化等前端知识和实战感兴趣,欢迎加入微信《趣谈前端》社群,与我们一起学习、讨论和探索前端技术的边界。