的rtmp流播放即可;
5. 教师和学生互动:学生端如需作为示范案例,屏幕数据共享给其他同学,只需请求同屏,数据反推到rtmp服务器,其他学生查看即可。
6. 扩展监控:如果需要更进一步的技术方案,如教师端想监控学生端的屏幕情况,可以有两种方案,如学生端直接推rtmp过来,或者,学生端启动内置rtsp服务,教师端想看的时候,随时看即可(亦可轮询播放)。
android端对接
推送分辨率如何设定或缩放?
android设备,特别是高分屏,拿到的视频原始宽高非
r语言-中国各城市pm2.5数据间的相关分析:近日,京津冀遭遇“雾霾锁成”,廊坊、保定、石家庄、邢台、邯郸成为污染最严重地区。 ?
很多网站提供了pm2.5(细颗粒物)及空气质量指数(aqi)的实时查询,比如:pm25.in、北京市环境检测中心等等。
这些网站只是对数据进行了展示,有的还做了很漂亮的可视化,但却没有做进一步的数据分析。舍恩伯格在《大数据时代》一书中这样写道:“我们没有必要非得知道现象背后的原因,而是要让数据自己发声。”
以及“相关关系能够帮助我们更好地了解这个世界。”他认为,建立在相关关系分析法上面的预测是大数据的核心。通过找到“关联物”并监控它,我们就能够预测未来。
,which(colnames(pm)天津市),which(colnames(pm)石家庄市)) knitr::kable(summary(pm)) 北京市天津市石家庄市min. : 30.00min
cloudbase cms + next.js:轻松构建一个内容丰富的站点:项目背景试想一下,如果你现在要为你自己或者你所在的组织创建一个强内容的站点,同时要求好的 seo(搜素引擎优化),比如博客,你会怎么做呢?
静态生成的意思是,在构建的过程中,next.js 就会自动执行数据拉取的逻辑,并把数据和 ui 渲染为一个个的静态 html 页面,这意味着,我们的站点将响应迅速,而且利于 seo。?
环境创建完毕后,进入扩展应用模块,可以看到“cms内容管理系统”,可以在这里安装它。设置都按照默认就可以了,唯一要注意的是,务必记住自己设置的管理员账号和密码。
,index.js 导出的函数式组件就直接对应着我们进入网站后的第一个页面,而其他 js 文件于 .pages 的相对地址就是 next.js 为其自动生成的路由。
可用于云端一体化开发多种端应用(小程序,公众号,web 应用,flutter 客户端等),帮助开发者统一构建和管理后端服务和云资源,避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现
重磅 | 万维网之父 tim berners-lee 荣获2016年度图灵奖:北京时间4月4日,美国计算机协会(association for computing machinery, 简称acm)宣布了 2016 年度图灵奖得主:万维网之父、mit 教授tim berners-lee
图灵奖由美国计算机协会于1966年设立,专门奖励那些对计算机事业作出重要贡献的个人。其名称取自计算机科学的先驱、英国科学家艾伦·麦席森·图灵(alan m. turing)。
图灵奖初期奖金为20万美元,1989年起增到25万美元,奖金通常由计算机界的一些大企业提供(通过与acm签订协议)。目前图灵奖由google赞助,奖金为100万美元。
他的成果包括创建网页命名方法(uri)、通信协议(http)和网页语言(html)。此外,他用开源代码编写了第一个浏览器。这使得早期的网页浏览器能推广到学术界以外。“第一个万维网网站在1991年上线。
“我感到荣幸能收到这个以计算机先锋命名的奖项。对于程序员来说,能用计算机来做什么,只能受到自己的限制。”tim教授表示。
dede模板首页,如何设计与seo?:从目前来看,有大量的中小型企业选择利用dede模板,建立企业网站,而在这个过程中,一个非常重要的问题就是企业网站首页的设计与优化。
特别是对于一些中小型企业,几乎网站内页根本不参与排名,所有的核心重点都在首页。 44.png 那么,dede模板,企业首页如何设计与优化?
④适当的增加随机新闻与热门新闻版块,提高网站内容更新的频率。
4、首页弹窗 在dede模板中,早期网站运营人员,最常用的一个方式就是加入广告弹窗代码,主要的用途包括: ①添加网站即时沟通组件 ②添加seo联盟的流量代码,用于商业变现。
总结:dede模板首页相关的设计与seo,仍然有诸多细节,而上述内容,仅供参考,更多优质内容,尽在seo优化课程。
「谷歌」hreflang标签知识与多国语言网站seo优化:今天跟各位同学讲解下有关hreflang标签的知识,如果,你有过优化多语言网站seo的经历,相信对这个标签并不陌生。希望,今天分享的内容能够对各位同学有所帮助。— — 及时当勉励,岁月不待人。
当一个网站采用国际网站时,最重要的技术seo元素之一就是hreflang标签。为什么hreflang标签如此重要?hreflang标签可帮助搜索引擎了解您的内容的哪个版本向哪些受众展示。
例如:瑞典语 - 不是se-se,而是sv-se。
对于电子商务网站或国际化平台,建议将hreflang标签添加到网站的站点地图中,这样可以更加实时更加方便的让搜索引擎知道该页面的相关信息。
今天的分页seo优化技巧知识就讲到这里了。如果,哪位同学有疑问的话,可以添加我个人微信号:seoiit,一起来讨论下。
电子政务系统的类型:旅游科普教育之android平台实现内网无纸化会议|智慧教室|实时同屏功能背景
本文主要讲的是基于android平台实现rtmp的技术方案设计,基础架构图如下:
组网注意事项
1. 组网:无线组网,需要好的ap模块才能撑得住大的并发流量,推送端到ap,最好是有线网链接;
2. 服务器部署:srs或nginx,服务器可以和windows平台的教师机部署在一台机器;
3. 教师端:如教师有移动的pad,可以直接推到rtmp服务器,然后共享出去;
4. 学生端:直接拉取服务端的rtmp流播放即可;
5. 教师和学生互动:学生端如需作为示范案例,屏幕数据共享给其他同学,只需请求同屏,数据反推到rtmp服务器,其他学生查看即可。
6. 扩展监控:如果需要更进一步的技术方案,如教师端想监控学生端的屏幕情况,可以有两种方案,如学生端直接推rtmp过来,或者,学生端启动内置rtsp服务,教师端想看的时候,随时看即可(亦可轮询播放)。
android端对接
推送分辨率如何设定或缩放?
android设备,特别是高分屏,拿到的视频原始宽高非常大,如果推原始分辨率,编码和上行压力大,所以,一般建议,适当缩放,比如宽高缩放至2/3,缩放一般建议等比例缩放,缩放宽高建议16字节对齐。
代码语言:javascript
复制
private void createscreenenvironment() {
sreenwindowwidth = mwindowmanager.getdefaultdisplay().getwidth();
screenwindowheight = mwindowmanager.getdefaultdisplay().getheight();
log.i(tag, "screenwindowwidth: " + sreenwindowwidth + ",screenwindowheight: "
+ screenwindowheight);
if (sreenwindowwidth > 800)
{
if (screenresolution == screen_resolution_standard)
{
scale_rate = scale_rate_half;
sreenwindowwidth = align(sreenwindowwidth / 2, 16);
screenwindowheight = align(screenwindowheight / 2, 16);
}
else if(screenresolution == screen_resolution_low)
{
scale_rate = scale_rate_two_fifths;
sreenwindowwidth = align(sreenwindowwidth * 2 / 5, 16);
}
}
log.i(tag, "after adjust mwindowwidth: " + sreenwindowwidth + ", mwindowheight: " + screenwindowheight);
int pf = mwindowmanager.getdefaultdisplay().getpixelformat();
log.i(tag, "display format:" + pf);
displaymetrics displaymetrics = new displaymetrics();
mwindowmanager.getdefaultdisplay().getmetrics(displaymetrics);
mscreendensity = displaymetrics.densitydpi;
mimagereader = imagereader.newinstance(sreenwindowwidth,
screenwindowheight, 0x1, 6);
mmediaprojectionmanager = (mediaprojectionmanager) getsystemservice(context.media_projection_service);
}
横竖屏自动适配
横竖屏状态下,采集的屏幕宽高不一样,如果横竖屏切换,这个时候,需要考虑到横竖屏适配问题,确保比如竖屏状态下,切换到横屏时,推拉流两端可以自动适配,横竖屏自动适配,编码器需要重启,拉流端,需要能自动适配宽高变化,自动播放。
代码语言:javascript
复制
public void onconfigurationchanged(configuration newconfig) {
try {
super.onconfigurationchanged(newconfig);
if (this.getresources().getconfiguration().orientation == configuration.orientation_landscape) {
log.i(tag, "onconfigurationchanged cur: landscape");
} else if (this.getresources().getconfiguration().orientation == configuration.orientation_portrait) {
log.i(tag, "onconfigurationchanged cur: portrait");
}
if(ispushingrtmp || isrecording || isrtsppublisherrunning)
{
stopscreencapture();
clearallimages();
createscreenenvironment();
setupvirtualdisplay();
}
} catch (exception ex) {
}
}
补帧策略
好多人不理解为什么要补帧,实际上,屏幕采集的时候,屏幕不动的话,不会一直有数据下去,这个时候,比较好的做法是,保存最后一帧数据,设定一定的补帧间隔,确保不会因为帧间距太大,导致播放端几秒都收不到数据,当然,如果服务器可以缓存gop,这个问题迎刃而解。
异常网络处理、事件回调机制
回答:如果是走rtmp,网络抖动或者其他网络异常,需要有好重连机制和状态回馈机制。
代码语言:javascript
复制
class eventhandev2 implements ntsmarteventcallbackv2 {
@override
public void onntsmarteventcallbackv2(long handle, int id, long param1, long param2, string param3, string param4, object param5) {
log.i(tag, "eventhandev2: handle=" + handle + " id:" + id);
string publisher_event = "";
switch (id) {
case ntsmarteventid.event_daniulive_erc_publisher_started:
publisher_event = "开始..";
break;
case ntsmarteventid.event_daniulive_erc_publisher_connecting:
publisher_event = "连接中..";
break;
case ntsmarteventid.event_daniulive_erc_publisher_connection_failed:
publisher_event = "连接失败..";
break;
case ntsmarteventid.event_daniulive_erc_publisher_connected:
publisher_event = "连接成功..";
break;
case ntsmarteventid.event_daniulive_erc_publisher_disconnected:
publisher_event = "连接断开..";
break;
case ntsmarteventid.event_daniulive_erc_publisher_stop:
publisher_event = "关闭..";
break;
case ntsmarteventid.event_daniulive_erc_publisher_recorder_start_new_file:
publisher_event = "开始一个新的录像文件 : " + param3;
break;
case ntsmarteventid.event_daniulive_erc_publisher_one_recorder_file_finished:
publisher_event = "已生成一个录像文件 : " + param3;
break;
case ntsmarteventid.event_daniulive_erc_publisher_send_delay:
publisher_event = "发送时延: " + param1 + " 帧数:" + param2;
break;
case ntsmarteventid.event_daniulive_erc_publisher_capture_image:
publisher_event = "快照: " + param1 + " 路径:" + param3;
if (param1 == 0) {
publisher_event = publisher_event + "截取快照成功..";
} else {
publisher_event = publisher_event + "截取快照失败..";
}
break;
case ntsmarteventid.event_daniulive_erc_publisher_rtsp_url:
publisher_event = "rtsp服务url: " + param3;
break;
case ntsmarteventid.event_daniulive_erc_push_rtsp_server_response_status_code:
publisher_event ="rtsp status code received, codeid: " + param1 + ", rtsp url: " + param3;
break;
case ntsmarteventid.event_daniulive_erc_push_rtsp_server_not_support:
publisher_event ="服务器不支持rtsp推送, 推送的rtsp url: " + param3;
break;
}
string str = "当前回调状态:" + publisher_event;
log.i(tag, str);
message message = new message();
message.what = publisher_event_msg;
message.obj = publisher_event;
handler.sendmessage(message);
}
}
部分屏幕数据采集
回答:我们遇到的好多场景下,教室端,会拿出来3/4的区域用来投递给学生看,1/4的区域,用来做一些指令等操作,这个时候,就需要考虑屏幕区域裁剪:
代码语言:javascript
复制
/**
* 投递裁剪过的rgba数据
*
* @param data: rgba data
*
* @param rowstride: stride information
*
* @param width: width
*
* @param height: height
*
* @param clipedleft: 左; clipedtop: 上; clipedwidth: 裁剪后的宽; clipedheight: 裁剪后的高; 确保传下去裁剪后的宽、高均为偶数
*
* @return {0} if successful
*/
public native int smartpublisheroncapturevideoclipedrgbadata(long handle, bytebuffer data, int rowstride, int width, int height, int clipedleft, int clipedtop, int clipedwidth, int clipedheight);
文字、图片水印
好多场景下,同屏者会把公司logo,和一定的文字信息展示在推送端,这个时候,需要考虑到文字和图片水印问题:
代码语言:javascript
复制
/**
* set text water-mark(设置文字水印)
*
* @param fontsize: it should be "medium", "small", "big"
*
* @param waterpostion: it should be "topleft", "topright", "bottomleft", "bottomright".
*
* @param xpading, ypading: the distance of the original picture.
*
* <pre> the interface is only used for setting font water-mark when publishing stream. </pre>
*
* @return {0} if successful
*/
public native int smartpublishersettextwatermark(long handle, string watertext, int isappendtime, int fontsize, int waterpostion, int xpading, int ypading);
/**
* set text water-mark font file name(设置文字水印字体路径)
*
* @param fontfilename: font full file name, e.g: /system/fonts/droidsansfallback.ttf
*
* @return {0} if successful
*/
public native int smartpublishersettextwatermarkfontfilename(long handle, string fontfilename);
/**
* set picture water-mark(设置png图片水印)
*
* @param picpath: the picture working path, e.g: /sdcard/logo.png
*
* @param waterpostion: it should be "topleft", "topright", "bottomleft", "bottomright".
*
* @param picwidth, picheight: picture width & height
*
* @param xpading, ypading: the distance of the original picture.
*
* <pre> the interface is only used for setting picture(logo) water-mark when publishing stream, with "*.png" format </pre>
*
* @return {0} if successful
*/
public native int smartpublishersetpicturewatermark(long handle, string picpath, int waterpostion, int picwidth, int picheight, int xpading, int ypading);
屏幕权限获取|数据采集
采集推送之前,需要获取屏幕权限,拿到屏幕数据后,调用sdk接口,完成推送或录像操作即可:
代码语言:javascript
复制
@targetapi(build.version_codes.lollipop)
private boolean startscreencapture() {
log.i(tag, "startscreencapture..");
setupmediaprojection();
setupvirtualdisplay();
return true;
}
private int align(int d, int a) {
return (((d) + (a - 1)) & ~(a - 1));
}
@suppresswarnings("deprecation")
@suppresslint("newapi")
private void createscreenenvironment() {
sreenwindowwidth = mwindowmanager.getdefaultdisplay().getwidth();
screenwindowheight = mwindowmanager.getdefaultdisplay().getheight();
log.i(tag, "screenwindowwidth: " + sreenwindowwidth + ",screenwindowheight: "
+ screenwindowheight);
if (sreenwindowwidth > 800)
{
if (screenresolution == screen_resolution_standard)
{
scale_rate = scale_rate_half;
sreenwindowwidth = align(sreenwindowwidth / 2, 16);
screenwindowheight = align(screenwindowheight / 2, 16);
}
else if(screenresolution == screen_resolution_low)
{
scale_rate = scale_rate_two_fifths;
sreenwindowwidth = align(sreenwindowwidth * 2 / 5, 16);
screenwindowheight = align(screenwindowheight * 2 / 5, 16);
}
}
log.i(tag, "after adjust mwindowwidth: " + sreenwindowwidth + ", mwindowheight: " + screenwindowheight);
int pf = mwindowmanager.getdefaultdisplay().getpixelformat();
log.i(tag, "display format:" + pf);
displaymetrics displaymetrics = new displaymetrics();
mwindowmanager.getdefaultdisplay().getmetrics(displaymetrics);
mscreendensity = displaymetrics.densitydpi;
mimagereader = imagereader.newinstance(sreenwindowwidth,
screenwindowheight, 0x1, 6);
mmediaprojectionmanager = (mediaprojectionmanager) getsystemservice(context.media_projection_service);
}
@suppresslint("newapi")
private void setupmediaprojection() {
mmediaprojection = mmediaprojectionmanager.getmediaprojection(
mainactivity.mresultcode, mainactivity.mresultdata);
}
@suppresslint("newapi")
private void setupvirtualdisplay() {
mvirtualdisplay = mmediaprojection.createvirtualdisplay(
"screencapture", sreenwindowwidth, screenwindowheight,
mscreendensity,
displaymanager.virtual_display_flag_auto_mirror,
mimagereader.getsurface(), null, null);
mimagereader.setonimageavailablelistener(
new imagereader.onimageavailablelistener() {
@override
public void onimageavailable(imagereader reader) {
image image = mimagereader.acquirelatestimage();
if (image != null) {
processscreenimage(image);
//image.close();
}
}
}, null);
}
private void startrecorderscreen() {
log.i(tag, "start recorder screen..");
if (startscreencapture()) {
new thread() {
@override
public void run() {
log.i(tag, "start record..");
}
}.start();
}
}
private bytebuffer deepcopy(bytebuffer source) {
int sourcep = source.position();
int sourcel = source.limit();
bytebuffer target = bytebuffer.allocatedirect(source.remaining());
target.put(source);
target.flip();
source.position(sourcep);
source.limit(sourcel);
return target;
}
/**
* process image data as desired.
*/
@suppresslint("newapi")
private void processscreenimage(image image) {
if(!ispushingrtmp && !isrecording &&!isrtsppublisherrunning)
{
image.close();
return;
}
/*
final image.plane[] planes = image.getplanes();
width_ = image.getwidth();
height_ = image.getheight();
row_stride_ = planes[0].getrowstride();
bytebuffer buf = deepcopy(planes[0].getbuffer());
*/
// log.i("onscreenimage", "new image");
pushimage(image);
}
@suppresslint("newapi")
private void stopscreencapture() {
if (mvirtualdisplay != null) {
mvirtualdisplay.release();
mvirtualdisplay = null;
}
}
基础初始化
代码语言:javascript
复制
private void initandsetconfig() {
//开始要不要采集音频或视频,请自行设置
publisherhandle = libpublisher.smartpublisheropen(this.getapplicationcontext(),
audio_opt, video_opt, sreenwindowwidth,
screenwindowheight);
if ( publisherhandle == 0 )
{
return;
}
log.i(tag, "publisherhandle=" + publisherhandle);
libpublisher.setsmartpublishereventcallbackv2(publisherhandle, new eventhandev2());
if(videoencodetype == 1)
{
int h264hwkbps = sethardwareencoderkbps(true, sreenwindowwidth,
screenwindowheight);
log.i(tag, "h264hwkbps: " + h264hwkbps);
int issupporth264hwencoder = libpublisher
.setsmartpublishervideohwencoder(publisherhandle, h264hwkbps);
if (issupporth264hwencoder == 0) {
log.i(tag, "great, it supports h.264 hardware encoder!");
}
}
else if (videoencodetype == 2)
{
int hevchwkbps = sethardwareencoderkbps(false, sreenwindowwidth,
screenwindowheight);
log.i(tag, "hevchwkbps: " + hevchwkbps);
int issupporthevchwencoder = libpublisher
.setsmartpublishervideohevchwencoder(publisherhandle, hevchwkbps);
if (issupporthevchwencoder == 0) {
log.i(tag, "great, it supports hevc hardware encoder!");
}
}
if(is_sw_vbr_mode)
{
int is_enable_vbr = 1;
int video_quality = calvideoquality(sreenwindowwidth,
screenwindowheight, true);
int vbr_max_bitrate = calvbrmaxkbitrate(sreenwindowwidth,
screenwindowheight);
libpublisher.smartpublishersetswvbrmode(publisherhandle, is_enable_vbr, video_quality, vbr_max_bitrate);
}
//音频相关可以参考smartpublisher工程
/*
if (!is_speex)
{
// set aac encoder
libpublisher.smartpublishersetaudiocodectype(publisherhandle, 1);
}
else
{
// set speex encoder
libpublisher.smartpublishersetaudiocodectype(publisherhandle, 2);
libpublisher.smartpublishersetspeexencoderquality(publisherhandle, 8);
}
libpublisher.smartpublishersetnoisesuppression(publisherhandle, is_noise_suppression ? 1
: 0);
libpublisher.smartpublishersetagc(publisherhandle, is_agc ? 1 : 0);
*/
// libpublisher.smartpublishersetclippingmode(publisherhandle, 0);
//libpublisher.smartpublishersetswvideoencoderprofile(publisherhandle, sw_video_encoder_profile);
//libpublisher.smartpublishersetswvideoencoderspeed(publisherhandle, sw_video_encoder_speed);
// libpublisher.setrtmppublishingtype(publisherhandle, 0);
libpublisher.smartpublishersetfps(publisherhandle, 18); //帧率可调
libpublisher.smartpublishersetgopinterval(publisherhandle, 18*3);
//libpublisher.smartpublishersetswvideobitrate(publisherhandle, 1200, 2400); //针对软编码有效,一般最大码率是平均码率的二倍
libpublisher.smartpublishersetswvideoencoderspeed(publisherhandle, 3);
//libpublisher.smartpublishersaveimageflag(publisherhandle, 1);
}
准备推送|录像|启动rtsp服务
代码语言:javascript
复制
@suppresswarnings("deprecation")
@override
public void onstart(intent intent, int startid) {
// todo auto-generated method stub
super.onstart(intent, startid);
log.i(tag, "onstart++");
if (libpublisher == null)
return;
clearallimages();
screenresolution = intent.getextras().getint("screenresolution");
videoencodetype = intent.getextras().getint("videoencodetype");
push_type = intent.getextras().getint("pushtype");
log.i(tag, "push_type: " + push_type);
mwindowmanager = (windowmanager) getsystemservice(service.window_service);
// 窗口管理者
createscreenenvironment();
startrecorderscreen();
//如果同时推送和录像,设置一次就可以
initandsetconfig();
if ( publisherhandle == 0 )
{
stopscreencapture();
return;
}
if(push_type == push_type_rtmp)
{
string publishurl = intent.getstringextra("publishurl");
log.i(tag, "publishurl: " + publishurl);
if (libpublisher.smartpublisherseturl(publisherhandle, publishurl) != 0) {
stopscreencapture();
log.e(tag, "failed to set publish stream url..");
if (publisherhandle != 0) {
if (libpublisher != null) {
libpublisher.smartpublisherclose(publisherhandle);
publisherhandle = 0;
}
}
return;
}
}
//启动传递数据线程
post_data_thread = new thread(new datarunnable());
log.i(tag, "new post_data_thread..");
is_post_data_thread_alive = true;
post_data_thread.start();
//录像相关++
is_need_local_recorder = intent.getextras().getboolean("recorder");
if(is_need_local_recorder)
{
configrecorderparam();
int startret = libpublisher.smartpublisherstartrecorder(publisherhandle);
if( startret != 0 )
{
isrecording = false;
log.e(tag, "failed to start recorder..");
}
else
{
isrecording = true;
}
}
//录像相关——
if(push_type == push_type_rtmp)
{
log.i(tag, "rtmp pusher mode..");
//推流相关++
int startret = libpublisher.smartpublisherstartpublisher(publisherhandle);
if (startret != 0) {
ispushingrtmp = false;
log.e(tag, "failed to start push rtmp stream..");
return;
}
else
{
ispushingrtmp = true;
}
//推流相关--
}
else if(push_type == push_type_rtsp)
{
log.i(tag, "rtsp internal server mode..");
rtsp_handle_ = libpublisher.openrtspserver(0);
if (rtsp_handle_ == 0) {
log.e(tag, "创建rtsp server实例失败! 请检查sdk有效性");
} else {
int port = 8554;
if (libpublisher.setrtspserverport(rtsp_handle_, port) != 0) {
libpublisher.closertspserver(rtsp_handle_);
rtsp_handle_ = 0;
log.e(tag, "创建rtsp server端口失败! 请检查端口是否重复或者端口不在范围内!");
}
//string user_name = "admin";
//string password = "12345";
//libpublisher.setrtspserverusernamepassword(rtsp_handle_, user_name, password);
if (libpublisher.startrtspserver(rtsp_handle_, 0) == 0) {
log.i(tag, "启动rtsp server 成功!");
} else {
libpublisher.closertspserver(rtsp_handle_);
rtsp_handle_ = 0;
log.e(tag, "启动rtsp server失败! 请检查设置的端口是否被占用!");
return;
}
isrtspservicerunning = true;
}
if(isrtspservicerunning)
{
log.i(tag, "onclick start rtsp publisher..");
string rtsp_stream_name = "stream1";
libpublisher.setrtspstreamname(publisherhandle, rtsp_stream_name);
libpublisher.clearrtspstreamserver(publisherhandle);
libpublisher.addrtspstreamserver(publisherhandle, rtsp_handle_, 0);
if (libpublisher.startrtspstream(publisherhandle, 0) != 0) {
log.e(tag, "调用发布rtsp流接口失败!");
return;
}
isrtsppublisherrunning = true;
}
}
//如果同时推送和录像,audio启动一次就可以了
checkinitaudiorecorder();
log.i(tag, "onstart--");
}
private void stoppush() {
if(!ispushingrtmp)
{
return;
}
if (!isrecording && !isrtsppublisherrunning) {
if (audiorecord_ != null) {
log.i(tag, "stoppush, call audiorecord_.stoprecording..");
audiorecord_.stop();
if (audiorecordcallback_ != null) {
audiorecord_.removecallback(audiorecordcallback_);
audiorecordcallback_ = null;
}
audiorecord_ = null;
}
}
if (libpublisher != null) {
libpublisher.smartpublisherstoppublisher(publisherhandle);
}
if (!isrecording && !isrtsppublisherrunning) {
if (publisherhandle != 0) {
if (libpublisher != null) {
libpublisher.smartpublisherclose(publisherhandle);
publisherhandle = 0;
}
}
}
}
停止推送|录像|rtsp服务
代码语言:javascript
复制
private void stoprecorder() {
if(!isrecording)
{
return;
}
if (!ispushingrtmp && !isrtsppublisherrunning) {
if (audiorecord_ != null) {
log.i(tag, "stoprecorder, call audiorecord_.stoprecording..");
audiorecord_.stop();
if (audiorecordcallback_ != null) {
audiorecord_.removecallback(audiorecordcallback_);
audiorecordcallback_ = null;
}
audiorecord_ = null;
}
}
if (libpublisher != null) {
libpublisher.smartpublisherstoprecorder(publisherhandle);
}
if (!ispushingrtmp && !isrtsppublisherrunning) {
if (publisherhandle != 0) {
if (libpublisher != null) {
libpublisher.smartpublisherclose(publisherhandle);
publisherhandle = 0;
}
}
}
}
//停止发布rtsp流
private void stoprtsppublisher() {
if(!isrtsppublisherrunning)
{
return;
}
if (!ispushingrtmp && !isrecording) {
if (audiorecord_ != null) {
log.i(tag, "stoprtsppublisher, call audiorecord_.stoprecording..");
audiorecord_.stop();
if (audiorecordcallback_ != null) {
audiorecord_.removecallback(audiorecordcallback_);
audiorecordcallback_ = null;
}
audiorecord_ = null;
}
}
if (libpublisher != null) {
libpublisher.stoprtspstream(publisherhandle);
}
if (!ispushingrtmp && !isrecording) {
if (publisherhandle != 0) {
if (libpublisher != null) {
libpublisher.smartpublisherclose(publisherhandle);
publisherhandle = 0;
}
}
}
}
//停止rtsp服务
private void stoprtspservice() {
if(!isrtspservicerunning)
{
return;
}
if (libpublisher != null && rtsp_handle_ != 0) {
libpublisher.stoprtspserver(rtsp_handle_);
libpublisher.closertspserver(rtsp_handle_);
rtsp_handle_ = 0;
}
}
感兴趣的开发者可酌情参考。
什么是互联网思维:@箐一 分享了她近期的感触,觉得有理儿,且易懂,“互联网思维就是让用户参与进来”:1)传统的烧烤:餐厅烤好,用户吃 > 不好吃,骂餐厅,一定是餐厅的错2)互联网思维的烧烤:用户自己烤,烤了自己吃 >
不好吃,有可能是自己烤的不好,参与了其中,即使烤糊了,也是很有成就感的同理:1)用户参与到产品的设计中来(小米的miui)2)用户参与到产品的传播中来(微博分享,好友圈分享)3)用户参与到产品的评价中来
(实体店的评论墙,电商网站的评论系统)4)…这些都是典型“互联网思维”的表现。
观点一,互联网思维是:1)免费:用户可能不会为核心业务直接买单,互联网公司不得不寻求其他利润途径,典型是360安全卫士的崛起2)快速:互联网竞争激烈,门槛不高,山寨成风,速度对互联网行业就是生命,跑得慢的都将被遗忘
一切的一切,都在大数据中蕴含4)极致思维:同观点一5)平台思维:平台思维的特点首先是开发,建立平台,建立生态圈,才能活的长久
2014世界杯:巴西该怎样利用大数据?:这套装置是一个国际团队多年研发的成果,这个团队里有科学家有工程师,他们都为一个叫做“重新站立起来”的项目工作。
atos是一家法国公司,他们将负责里约奥运会的信息技术网络,他们说在2012年伦敦奥运会的时候侦查到两亿五千五百万次安全事件。
作为一个科学家,他开始了自己的探索。他使用了12,000个价格数据做研究,数据都是从旅游网站上抓取下来的,时间跨度有41天。他建立了一个预测模型,用这个模型他能为虚拟客人省下不少钱。
又过了几年,这项技术就面世了。旅游网站amadeus已经在跟你分享很多信息诸如:- 人们都是在哪里搜索机票信息的?- 大多数飞机航线从哪里出发?- 机票的收入和回报是怎样的?
南非世界杯过后,南非的游客增长了22%。可口可乐的社会数据实验就像其他精明的跨国公司一样,可口可乐也希望让自己的品牌充斥你的生活。他们想让你喝可口可乐,该如何达到这个目的呢?没错,还是大数据。
web前端学习 第2章 网页重构1 第一个网页:0.png 一、内容概述从本节我们开始正式学习前端开发的课程内容,首先我们从第一个网页开始了解html和css的基本概念,并通过创建第一个网页了解vscode的基本使用方法。
网页文件本身是一种文本文件, 使用 !
庆幸的是有了这本《前端开发学习手册》,只要掌握十几个标签,就能完成生动的网页。在下一节我们会列举常用的html标签。
刚才我们了解了,使用html可以设置网页中的内容(标准通用标记语言的一个应用)等文件样式的计算机语言,那么使用css就可以进一步装饰这些内容,录入设置文本的字体颜色,或是改变图片的尺寸等等。
1 2 3 4 5 6 document 7 8 p{ 9 color:red;10 }11 12 13 14 我的第一个网页15 16 上面的代码我们可以将p标签的文字设置成红色。
ccf业务总部和学术交流中心落户苏州相城:2019年1月12日,中国计算机学会(ccf)与苏州市相城区人民政府、苏州高铁新城管委会在苏州高铁金科大酒店联合举办了ccf业务总部&学术交流中心落地苏州相城签约仪式及新闻发布会,ccf理事长高文,秘书长杜子德
签约仪式由相城区副区长朱小海主持。
同时ccf还将深入建设线上服务和区域会员服务以及其他和ccf发展有关的业务,线上服务包括但不限于ccf网站、数字图书馆、ccf在线、会议管理服务、会员管理和服务等。
苏州市相城区人民政府和苏州高铁新城管理委员会将对建设和运营ccf业务总部&学术交流中心提供相关有效支持,帮助ccf基于苏州做好区域辐射服务。 ?
签约仪式上,ccf理事长高文,ccf前任副理事长、中国工程院副院长陈左宁,苏州市政府副秘书长卢渊,苏州市科协主席程波,相城区委书记顾海东的共同见证下,杜子德、潘春华、苏学庆在合作协议上签字。
1分钟链圈 | 今日波场虚拟机tvm正式上线,大幅降低dapp运营成本::区块链在数据分析领域仍有很大空间人民网:区块链技术或将解决传媒业信源追溯、版权保护等痛点公司纽交所上市公司vmware推出区块链项目concord,用于数字共识和智能合同执行郑州银行:将利用区块链技术打造商贸物流
“智慧平台”国内首家互联网保险公司众安在线研发上半年投入同比增加91%,已形成t系列区块链产品五条科技产品线恭喜你,今天的新闻全部看完啦。
1.今日波场虚拟机tvm正式上线,大幅降低dapp运营成本 今日波场虚拟机tvm正式上线,在直播中,波场技术负责人赵宏着重介绍了波场虚拟机的特性,除在测试版时已公布的“完全兼容以太坊虚拟机”外,赵宏表示
10.郑州银行:将利用区块链技术打造商贸物流“智慧平台”根据新浪财经消息,郑州银行将充分利用郑州市作为国家中心城市、“一带一路”重要节点城市的优势,加强与电商巨头、物流公司、物流园区的合作,通过聚集广泛的金融资源
,借助大数据、区块链等新技术,打造商贸物流“智慧平台”,聚焦解决会员企业的资金流、信息流、物流等痛点难点问题,力推实现商贸物流金融领域“商流、物流、资金流、信息流”的四流合一,推进商贸物流金融模式的创新发展
大数据与商业地理分析:接下来,深入到每一个街道分区内部,根据分区特征、商业信息点的分布与区域聚集度进行打分,结合该城市各分区内已建在建筹建楼宇列表选出网点的最优位置(见图1)。?
即使是城市轨道交通建设这样长期而浩大的工程,商业地理分析亦能提供独特的视角。近期我们获邀为西南某省会城市的轨道交通发展把脉。从地理空间的角度来考察地铁规划再合适不过。
全面竣工后39%的城市人口将会在地铁站点周边800米内。但与伦敦和莫斯科等国际都市相比,地铁站点密度仍然偏低。
同时,半数以上的医院和学校超出了地铁站点800米覆盖范围,站点附近尚缺乏足够的配套公共服务设施。进一步分析发现,还有部分地铁站点周围人口稀疏且商业活动不频繁,可能是城市中的价值洼地(见图3)。??
过去几年,在麦肯锡全球商业地理分析团队的帮助和多方努力下,我们已经构建了深入到街道级别的地理信息数据库,涵盖近千万的商业信息点,并已经应用于数十个客户项目的分析中,在中国处于领先地位。
转载请注明出处,本站网址:
http://www.515158.com/news/2064.html