前言

公司业务需要,PC端,移动端都用到了第三方 网易云信 IM来实现在线客服咨询。

在这当中难免遇到一些需求是网易云信没有提供,需要自行编码进行扩展的。写此篇文章的目的正是因业务需要,需要在网易云信的基础上进行消息类型的扩展。

如下图所示的消息类型

带图片和文字,并且可点击的消息类型,(注意收到的消息和发送的消息文本颜色不一样)

标题是iOS版,可想而知,肯定还有其他如 Android版,Web版等,不可能此类型的消息(我称它为图文消息)只支持iOS,而在Android或Web端无法显示问题。以下附上其他版本扩展的链接

正文

下载demo后,双击 NIMDemo/NIM.xcworkspace 打开项目,然后运行,确保下载下来的demo能正确运行起来。

运行没有问题后,修改以下几个文件配置,将demo修改为自己所用。

修改 Classes/Util/NTESDemoConfig.m中的_appKey,填入自己的appKey

- (instancetype)init

{

if (self = [super init])

{

_appKey = @"填入自己的appKey";

_apiURL = @"https://app.netease.im/api";

_apnsCername = @"ENTERPRISE";

_pkCername = @"DEMO_PUSH_KIT";

_redPacketConfig = [[NTESRedPacketConfig alloc] init];

}

return self;

}

修改

- (NSString *)tokenByPassword

{

//demo直接使用username作为account,md5(password)作为token

//接入应用开发需要根据自己的实际情况来获取 account和token

//return [[NIMSDK sharedSDK] isUsingDemoAppKey] ? [self MD5String] : self;

return [self MD5String];

}

修改上述代码后,重新运行,即可使用自己的账号密码登录了。

添加测试发送图文链接的按钮,点击即发送图文链接消息

编辑NTESCellLayoutConfig.m文件,在init函数中 _types 增加一条

- (instancetype)init

{

if (self = [super init])

{

_types = @[

@"NTESJanKenPonAttachment",

@"NTESSnapchatAttachment",

@"NTESChartletAttachment",

@"NTESWhiteboardAttachment",

@"NTESRedPacketAttachment",

@"NTESRedPacketTipAttachment",

// 添加图文链接消息

@"NTESLinkAttachment"

];

_sessionCustomconfig = [[NTESSessionCustomContentConfig alloc] init];

_chatroomTextConfig = [[NTESChatroomTextContentConfig alloc] init];

_chatroomRobotConfig = [[NTESChatroomRobotContentConfig alloc] init];

}

return self;

}

编辑 NTESCustomAttachmentDecoder.m文件,checkAttachment函数中添加如下代码

//头部导入

#import "NTESLinkAttachment.h"

//...

- (id)decodeAttachment:(NSString *)content

{

id attachment = nil;

NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];

if (data) {

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data

options:0

error:nil];

if ([dict isKindOfClass:[NSDictionary class]])

{

NSInteger type = [dict jsonInteger:CMType];

NSDictionary *data = [dict jsonDict:CMData];

switch (type) {

//...

// 添加图文链接 case

case CustomMessageTypeLink:

{

attachment = [[NTESLinkAttachment alloc] init];

((NTESLinkAttachment *)attachment).title = [data jsonString:CMLinkPacketTitle];

((NTESLinkAttachment *)attachment).linkUrl = [data jsonString:CMLinkPacketLinkUrl];

((NTESLinkAttachment *)attachment).imageUrl = [data jsonString:CMLinkPacketImageUrl];

((NTESLinkAttachment *)attachment).describe = [data jsonString:CMLinkPacketDescribe];

}

break;

default:

break;

}

attachment = [self checkAttachment:attachment] ? attachment : nil;

}

}

return attachment;

}

- (BOOL)checkAttachment:(id)attachment

{

// ... 省略前面的 if else if 块

// 添加如下代码

else if ([attachment isKindOfClass:[NTESLinkAttachment class]])

{

check = YES;

}

return check;

}

编辑NTESSessionConfig.m文件,在mediaItems函数中添加如下代码

//...

// 添加图文链接测试按钮,此处的 onTapMediaItemLinkPacket 在

NTESSessionViewController.m 中添加

NIMMediaItem *linkPacket = [NIMMediaItem item:@"onTapMediaItemLinkPacket:"

normalImage:[UIImage imageNamed:@"icon_redpacket_normal"]

selectedImage:[UIImage imageNamed:@"icon_redpacket_pressed"]

title:@"图文链接"];

//...

if (isMe)

{

items = @[janKenPon,fileTrans,tip];

}

else if(_session.sessionType == NIMSessionTypeTeam)

{

// 在群组消息里添加

items = @[janKenPon,teamMeeting,fileTrans,tip,redPacket,linkPacket];

}

else

{

// 添加图文链接测试按钮

items = @[janKenPon,audioChat,videoChat,fileTrans,snapChat,whiteBoard,tip,redPacket,linkPacket];

}

在 Classes/Sections/Session/Object/Attach目录下创建 NTESLinkAttachment文件,继承 NSObject类,实现 NIMCustomAttachment,NTESCustomAttachmentInfo协议

创建Cocoa Touch Class文件 NTESLinkAttachment,命名规则尽量遵循云信命名规则

创建完成后,添加响应的属性值 标题title,跳转的链接linkUrl,图片imageUrl,描述describe。

NTESLinkAttachment.h文件内容如下

#import

#import "NTESCustomAttachmentDefines.h"

@interface NTESLinkAttachment : NSObject

// 标题

@property (nonatomic, copy) NSString *title;

// 点击跳转的链接地址

@property (nonatomic, copy) NSString *linkUrl;

// 图片

@property (nonatomic, copy) NSString *imageUrl;

// 描述

@property (nonatomic, copy) NSString *describe;

@end

NTESLinkAttachment.m文件内容如下

复制之后,会有报错如 NTESSessionLinkContentView.h找不到,和 CMLinkPacket***未定义等相关错误,先别急,后面会讲到,如果看不顺眼可以先注释掉,回头再过来放开注释也行。(ps:本人非iOS开发,所以代码部分不做详细讲解)

#import "NTESLinkAttachment.h"

#import "NTESSessionLinkContentView.h"

@implementation NTESLinkAttachment

- (NSString *)encodeAttachment

{

NSDictionary *dict = @{

CMType : @(CustomMessageTypeRedPacket),

CMData : @{

CMLinkPacketTitle : self.title,

CMLinkPacketLinkUrl : self.linkUrl,

CMLinkPacketImageUrl : self.imageUrl,

CMLinkPacketDescribe : self.describe

}

};

NSData *data = [NSJSONSerialization dataWithJSONObject:dict

options:0

error:nil];

NSString *content = nil;

if (data) {

content = [[NSString alloc] initWithData:data

encoding:NSUTF8StringEncoding];

}

return content;

}

- (NSString *)cellContent:(NIMMessage *)message{

return @"NTESSessionLinkContentView";

}

- (CGSize)contentSize:(NIMMessage *)message cellWidth:(CGFloat)width{

CGFloat w = 240.0f;

CGFloat h = 40.0f;

CGFloat padding = 3.0f * 3;

if (self.imageUrl != nil) {

h += 140.f;

}

if (self.describe != nil) {

UIFont *font = [UIFont systemFontOfSize:12.0];

CGFloat height = [NTESSessionLinkContentView getHeightByWidth:w - padding title:self.describe font:font];

h += height + padding;

}

return CGSizeMake(w, h);

}

- (UIEdgeInsets)contentViewInsets:(NIMMessage *)message

{

CGFloat bubblePaddingForImage = 3.f;

CGFloat bubbleArrowWidthForImage = 5.f;

if (message.isOutgoingMsg) {

return UIEdgeInsetsMake(bubblePaddingForImage,bubblePaddingForImage,bubblePaddingForImage,bubblePaddingForImage + bubbleArrowWidthForImage);

}else{

return UIEdgeInsetsMake(bubblePaddingForImage,bubblePaddingForImage + bubbleArrowWidthForImage, bubblePaddingForImage,bubblePaddingForImage);

}

}

- (BOOL)canBeRevoked

{

return YES;

}

- (BOOL)canBeForwarded

{

return YES;

}

@end

现在再来补充上面缺失的部分。

在 NTESCustomAttachmentDefines.h文件中定义如下四个字段。打开这个文件可以看到这个里面还定义了一些其他消息需要用到的字段,所以遵循人家的游戏规则,也在此处定义。

//...省略

typedef NS_ENUM(NSInteger,NTESCustomMessageType){

CustomMessageTypeJanKenPon = 1, //剪子石头布

CustomMessageTypeSnapchat = 2, //阅后即焚

CustomMessageTypeChartlet = 3, //贴图表情

CustomMessageTypeWhiteboard = 4, //白板会话

// (由于我其他平台图文消息type是5,刚好我们业务不需要发红包功能,这里我只好把5变成我的图文消息,把红包类型的消息去除)

CustomMessageTypeRedPacket = 5, //红包消息

CustomMessageTypeRedPacketTip = 6, //红包提示消息

};

//...省略

//红包

#define CMRedPacketTitle @"title" //红包标题

#define CMRedPacketContent @"content" //红包内容

#define CMRedPacketId @"redPacketId" //红包ID

//红包详情

#define CMRedPacketSendId @"sendPacketId"

#define CMRedPacketOpenId @"openPacketId"

#define CMRedPacketDone @"isGetDone"

// 添加此处四个字段用于图文链接消息使用

#define CMLinkPacketTitle @"title" //标题

#define CMLinkPacketLinkUrl @"link_url" //跳转链接

#define CMLinkPacketImageUrl @"image_url" //图片链接

#define CMLinkPacketDescribe @"describe" //描述

//...省略

在Classes/Sections/Session/View/SessionCell/SessionContentView目录下创建Cocoach Touch Class文件 NIMSessionMessageContentView,此文件主要用来做图文链接消息的显示。

NIMSessionMessageContentView.h文件内容如下

#import "NIMSessionMessageContentView.h"

static NSString *const NIMDemoEventNameLinkingPacket = @"NIMDemoEventNameLinkingPacket";

@interface NTESSessionLinkContentView : NIMSessionMessageContentView

// 根据宽度,字体和文本内容获取高度

+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font;

@end

NIMSessionMessageContentView.m文件内容如下

#import "NTESSessionLinkContentView.h"

#import "UIView+NTES.h"

#import "NTESLinkAttachment.h"

#import "NTESSessionUtil.h"

#import "UIImageView+WebCache.h"

CGFloat titleHeight = 40.f; // title高度

CGFloat imageHeight = 120.f;// 图片高度

@interface NTESSessionLinkContentView()

// 图文链接消息附件

@property (nonatomic,strong) NTESLinkAttachment *attachment;

@property (nonatomic,strong) UILabel *titleLabel;

@property (nonatomic,strong) UIImageView *imageView;

@property (nonatomic,strong) UILabel *describeLabel;

@end

@implementation NTESSessionLinkContentView

- (instancetype)initSessionMessageContentView{

self = [super initSessionMessageContentView];

if (self) {

self.opaque = YES;

_titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];

_imageView = [[UIImageView alloc] initWithFrame:CGRectZero];

_describeLabel = [[UILabel alloc] initWithFrame:CGRectZero];

}

return self;

}

- (void)refresh:(NIMMessageModel *)data

{

[super refresh:data];

NIMCustomObject *customObject = (NIMCustomObject*)data.message.messageObject;

id attach = customObject.attachment;

if ([attach isKindOfClass:[NTESLinkAttachment class]]) {

self.attachment = (NTESLinkAttachment *)attach;

self.titleLabel.text = self.attachment.title;

[self addSubview:_titleLabel];

if (self.attachment.imageUrl != nil) {

NSURL *url = [NSURL URLWithString:self.attachment.imageUrl];

// 默认图片 default_image,记得在 Images.xcassets 中添加

[self.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"default_image"]];

[self.imageView sizeToFit];

[self addSubview:_imageView];

}

if (self.attachment.describe != nil) {

self.describeLabel.text = self.attachment.describe;

[self addSubview:_describeLabel];

}

}

}

- (void)layoutSubviews{

[super layoutSubviews];

BOOL outgoing = self.model.message.isOutgoingMsg;

UIEdgeInsets contentInsets = self.model.contentViewInsets;

CGSize contentSize = [self.model contentSize:self.superview.width];

CGFloat padding = 15;

self.titleLabel.frame = CGRectMake(padding, contentInsets.left, contentSize.width - padding, titleHeight);

self.titleLabel.font = [UIFont systemFontOfSize:14.0];

self.titleLabel.numberOfLines = 1;

// 详情描述距离

CGFloat describeY = titleHeight;

if (self.attachment != nil && self.attachment.imageUrl != nil) {

self.imageView.frame = CGRectMake(

contentInsets.left + contentInsets.right,

titleHeight + contentInsets.top + 5,

contentSize.width - (contentInsets.left + contentInsets.right), imageHeight);

self.imageView.contentMode = UIViewContentModeScaleAspectFit;

[self setBorderWithImageView:self.imageView top:TRUE left:FALSE bottom:TRUE right:FALSE borderColor:[UIColor lightGrayColor] borderWidth:0.3f];

describeY += imageHeight + contentInsets.top * 3 + 5 ;

}

if (self.attachment != nil && self.attachment.describe != nil) {

UIFont *font = [UIFont systemFontOfSize:12.0];

self.describeLabel.font = font;

self.describeLabel.numberOfLines = 3;

CGFloat height = [NTESSessionLinkContentView getHeightByWidth:self.describeLabel.frame.size.width title:self.attachment.describe font:font];

self.describeLabel.frame = CGRectMake(padding, describeY, contentSize.width - padding, height + padding);

}

// 发出去的消息

if (outgoing)

{

self.titleLabel.textColor = [UIColor whiteColor];

self.describeLabel.textColor = [UIColor whiteColor];

}

else

{

self.titleLabel.textColor = [UIColor blackColor];

self.describeLabel.textColor = [UIColor grayColor];

}

}

// 根据宽动态获取高度

+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font

{

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 0)];

label.text = title;

label.font = font;

label.numberOfLines = 0;

[label sizeToFit];

CGFloat height = label.frame.size.height;

return height;

}

// 设置元素边框

-(void)setBorderWithImageView:(UIImageView *) imageView top:(BOOL)top left:(BOOL)left bottom:(BOOL)bottom right:(BOOL)right borderColor:(UIColor *)color borderWidth:(CGFloat)width

{

// 垂直内边距

CGFloat verticalPadding = 5.0f;

if (top)

{

CALayer *layer = [CALayer layer];

layer.frame = CGRectMake(0, -verticalPadding, imageView.frame.size.width, width);

layer.backgroundColor = color.CGColor;

[imageView.layer addSublayer:layer];

}

if (left)

{

CALayer *layer = [CALayer layer];

layer.frame = CGRectMake(0, 0, width, imageView.frame.size.height);

layer.backgroundColor = color.CGColor;

[imageView.layer addSublayer:layer];

}

if (bottom)

{

CALayer *layer = [CALayer layer];

layer.frame = CGRectMake(0, imageView.frame.size.height - width + verticalPadding, imageView.frame.size.width, width);

layer.backgroundColor = color.CGColor;

[imageView.layer addSublayer:layer];

}

if (right)

{

CALayer *layer = [CALayer layer];

layer.frame = CGRectMake(imageView.frame.size.width - width, 0, width, imageView.frame.size.height);

layer.backgroundColor = color.CGColor;

[imageView.layer addSublayer:layer];

}

}

- (void)onTouchUpInside:(id)sender

{

if ([self.delegate respondsToSelector:@selector(onCatchEvent:)]) {

NIMKitEvent *event = [[NIMKitEvent alloc] init];

event.eventName = NIMDemoEventNameLinkingPacket;

event.messageModel = self.model;

event.data = self;

[self.delegate onCatchEvent:event];

}

}

@end

接下来我们添加图文按钮的点击事件处理。

下面代码添加此处按钮点击处理事件

打开文件 NTESSessionViewController.m, 编辑函数 onTapCell

在 if else if 代码块后面添加如下代码

// 头部需导入

#import "NTESLinkAttachment.h"

#import "NTESSessionLinkContentView.h"

#import "NTESWebViewController.h"

// ...

// 添加图文链接消息点击事件

else if ([eventName isEqualToString:NIMDemoEventNameLinkingPacket]) {

NIMCustomObject *object = event.messageModel.message.messageObject;

NTESLinkAttachment *attachment = (NTESLinkAttachment *)object.attachment;

[self onOpenWebView:attachment];

handled = YES;

}

// ....

// 添加上面调用的 onOpenWebView 函数

- (void)onOpenWebView:(NTESLinkAttachment *)attachment {

// NTESWebViewController 是点击显示的图文消息后要跳转的页面,在构造函数添加跳转时传入 linkUrl

NTESWebViewController *vc = [[NTESWebViewController alloc] initWithUrl:attachment.linkUrl];

// 设置title

if (attachment && attachment.title != nil) {

vc.title = attachment.title;

}

[self.navigationController pushViewController:vc animated:YES];

}

//...

#pragma mark - 图文链接

- (void)onTapMediaItemLinkPacket:(NIMMediaItem *)item

{

// 此处模拟测试数据

NTESLinkAttachment *attachment = [[NTESLinkAttachment alloc] init];

[attachment setTitle:@"暖冬季欢乐送"];

[attachment setLinkUrl:@"https://www.jianshu.com/u/bd57ade96e8a"];

[attachment setImageUrl:@"https://www.baidu.com/img/bd_logo1.png"];

[attachment setDescribe:@"家具满1000元减100元再返100元现金券!点击查看详情!"];

NIMMessage *message = [NTESSessionMsgConverter msgWithLink:attachment];

[self sendMessage:message];

}

//...

在目录 Classes/Sections/Session/ViewController添加上面使用到的 NTESWebViewController,用来显示点击后的网页

NTESWebViewController.h内容如下

#import

@interface NTESWebViewController : UIViewController

{

UIWebView *webView;

}

- (instancetype)initWithUrl:(NSString *)url;

@end

NTESWebViewController.m内容如下

#import "NTESWebViewController.h"

@interface NTESWebViewController ()

@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;

@property (nonatomic, strong) NSString *url;

@end

@implementation NTESWebViewController

- (instancetype)initWithUrl:(NSString *)url

{

self = [super init];

if (self)

{

_url = url;

}

return self;

}

- (void)viewDidLoad {

[super viewDidLoad];

// app 尺寸,去掉状态栏

CGRect mainScreen = [UIScreen mainScreen].applicationFrame;

// 1.创建webview,并设置大小

webView = [[UIWebView alloc] initWithFrame:CGRectMake(mainScreen.origin.x, mainScreen.origin.y, mainScreen.size.width, mainScreen.size.height)];

// 2.创建请求

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];

// 3.加载网页

[webView loadRequest:request];

// 4.将webview添加到界面

[self.view addSubview:webView];

[webView setDelegate:self];

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

- (void)webViewDidStartLoad:(UIWebView *)webView {

// 创建UIActivityIndicatorView背底半透明View

CGRect mainScreen = [UIScreen mainScreen].applicationFrame;

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(mainScreen.origin.x, mainScreen.origin.y, mainScreen.size.width, mainScreen.size.height)];

[view setTag:108];

[view setBackgroundColor:[UIColor whiteColor]];

[self.view addSubview:view];

self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 40.0f, 40.0f)];

[self.activityIndicator setCenter:view.center];

[self.activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];

[view addSubview:self.activityIndicator];

[self.activityIndicator startAnimating];

}

- (void)webViewDidFinishLoad:(UIWebView *)webView {

[self.activityIndicator stopAnimating];

UIView *view = (UIView *)[self.view viewWithTag:108];

[view removeFromSuperview];

}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {

[self.activityIndicator stopAnimating];

UIView *view = (UIView *)[self.view viewWithTag:108];

[view removeFromSuperview];

}

@end

添加显示自定义的图文消息

上面第3个步骤其实已经做了大部分自定义的图文链接消息的显示工作了,此处添加图文链接消息的转换代码,

编辑NTESSessionMsgConverter.h头文件

// ...

@class NTESLinkAttachment

@interface NTESSessionMsgConverter : NSObject

// ...

// 添加链接消息

+ (NIMMessage *)msgWithLink:(NTESLinkAttachment *)attachment;

@end

在实现文件NTESSessionMsgConverter.m添加以下代码

//...

#import "NTESLinkAttachment.h"

@implementation NTESSessionMsgConverter

//...

+ (NIMMessage *)msgWithLink:(NTESLinkAttachment *)attachment

{

NIMMessage *message = [[NIMMessage alloc] init];

NIMCustomObject *customObject = [[NIMCustomObject alloc] init];

customObject.attachment = attachment;

message.messageObject = customObject;

message.apnsContent = @"发来了链接信息";

return message;

}

@end

5.修改消息列表中,显示的缩略文字

添加显示[图文链接]字样,如果不添加,默认显示的是[未知消息]

编辑 NTESSessionListViewController.m, 在contentForRecentSession中添加一条逻辑判断

// ...

#import "NTESLinkAttachment.h"

// ...

- (NSAttributedString *)contentForRecentSession:(NIMRecentSession *)recent{

//...

else if ([object.attachment isKindOfClass:[NTESLinkAttachment class]]) {

text = @"[图文链接]";

} else {

text = @"[未知消息]";

}

//...

}

// ...

尾篇

到此,云信iOS端的扩展自定义消息已经完成。当然,这只是iOS的显示正常了,其他如web,Android,pc等客户端收到此类的消息,显示有问题,也是需要扩展调整的。此篇文章其他端的文章我会陆续更新,如果有需要的同学可以关注下。

以下附上其他版本扩展的链接

ios云信不能全屏_网易云信-新增自定义消息(iOS版)相关推荐

  1. html5的video在IOS端默认全屏和黑屏问题

    最近项目中需要使用video来代替有点复杂的动画(video循环自动播放),遇到了使用过程中的两个坑 ios端默认全屏解决办法 查阅资料说在在video标签加如下属性 <video webkit ...

  2. ios html5 自动全屏播放,禁止iPhone Safari video标签视频自动全屏的办法

    最近做一个移动端微信页面项目,在微信页面中有视频播放,但是需要禁止IOS的自动全屏播放(前提必须使用video标签). 如: 在iPhone safari 点击视频会弹出播放器进行全屏播放. 在网上看 ...

  3. 网易云信im即时通讯,php网易云信im即时通讯,tp,demo,即时通讯

    请先配置appKey和appSecret     本demo实现了服务端和web的联调(系统通知) 服务端参考文档:开发者中心 WEB参考文档:开发者中心 目录 1.公共类 Common.php 2. ...

  4. php网易云信如何使用,如何使用网易云信实现匿名聊天

    手机端的 APP 如果嵌入了 IM 模块,比如网易云信(环信),这些第三方的服务都有自己的账户系统,也是需要注册登录. 现在有这么一个需求:如何实现匿名聊天?同时要实现实名聊天. 需求可以简单理解为: ...

  5. apple设置中如果变全屏_如何从Apple Batterygate结算中获得25

    apple设置中如果变全屏 The class-action lawsuit was sparked after Apple admitted in December 2017 it had been ...

  6. 猿团专访云信CTO阙杭宁——网易云信“稳定”背后的秘密

    阙杭宁如何带领团队打造云信? 云信稳定背后有着怎样的秘密? 下文选自猿团对云信CTO阙杭宁的专访稿 原文来源中国网,内容排版有删改 "网易出品,必属精品",开发界流传的这句话对于大 ...

  7. iOS任何界面全屏炫酷倒计时,一句代码就够了

    概述 iOS全屏炫酷倒计时,任何界面只需要调用一句代码就能实现,支持定制倒计时数字.倒计时结束时显示的文本.支持倒计时播放图片.开始倒计时和结束倒计时的block和delegate回调.支持定制文本颜 ...

  8. jquery video全屏_用videojs让HTML5视频在移动端全屏的方法

    用videojs让HTML5视频在移动端全屏的方法 文章标签: 视频 : 04-10 19:23 : 1859次 : 0条 1赞 点赞 简介在使用videojs插件时,如何让HTML5的视频在移动端里 ...

  9. (已解决)video标签在ios端默认全屏播放(h5开发)

    Video在ios全屏播放 这两天一直在做h5开发,项目马上完结,就是到最后项目上线之后,在ios上面测试,突然发现原来的视频默认全屏播放,这样就有很大的限制,很不利于开发,我这边是已经解决这个问题了 ...

  10. 屏幕测试图片全屏_全屏视频测试

    屏幕测试图片全屏 只需记录一些全屏视频技术以及jQuery UI对话框窗口即可 . 我已经在演示中嵌入了YouTube视频,但是您可以嵌入任何视频. 在GitHub上 查看演示 查看项目 正在检查浏览 ...

最新文章

  1. 超好用的推广引流方法,看完赶紧用!
  2. Python全栈(第一部分)day2
  3. centos系统 anaconda3(python3)安装pygrib
  4. WmS详解(一)之token到底是什么?基于Android7.0源码
  5. 简单安装和yum安装的区别
  6. 八大排序算法交换排序算法
  7. 【转】WPF自定义控件与样式(3)-TextBox RichTextBox PasswordBox样式、水印、Label标签、功能扩展...
  8. Leetcode--329. 矩阵中的最长递增路径
  9. android录音播放列表,android数据库里的视频,图片,音频表
  10. win10语音语言服务器,win10系统:朗读女语音库(发音人)安装方法说明
  11. python基础知识-Python语言基础知识总结
  12. 24. 使用GitHub
  13. java线程卖票_Java通过卖票理解多线程
  14. Excel中快速填充产生连续的数字编号
  15. 音乐格式怎么转换,音频格式转换的方法
  16. DataSciComp 有关数据科学的比赛
  17. scratch字母点头问好 电子学会图形化编程scratch等级考试一级真题和答案2020-9
  18. PLC低频测速(T法测速)
  19. 分别解释final,finally,finalize是什么?
  20. 在线招聘市场强手如林,携AI入局的灵鸽会飞向何方?

热门文章

  1. 防爆机器人布里茨还能买到吗_LOL防暴机器人 布里茨皮肤
  2. Maven配置文件示例
  3. CVPR2022Oral专题系列(一):低光增强
  4. 苹果电脑各型号支持的macOS版本列表
  5. Virtual Network----网卡offload特性和网络加速技术简述
  6. 【后端架构完善与接口开发】003-新增ebook表,生成持久层代码
  7. 和腾讯大牛的技术面谈,面试总结
  8. Mobi格式的书籍整理
  9. mysql 锁级别说明 (行级锁)三
  10. OpenGL光源光照基础