『从零开始学小程序』媒体组件video组件
Posted starry陆离
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『从零开始学小程序』媒体组件video组件相关的知识,希望对你有一定的参考价值。
👨🎓作者简介:一位喜欢写作,计科专业大三菜鸟
🏡个人主页:starry陆离
🕒首发日期:2022年9月15日星期四
如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦
『从零开始学小程序』媒体组件video组件
1.简介
多媒体包括音频、视频和相机等,为了更好地在小程序中使用这些多媒体功能,微信官方也为开发者提供了一系列多媒体组件和API接口。多媒体组件如下所示:
- video组件:视频组件
- camera组件:相机组件
- audio组件:音频组件
- image组件:图片组件
video,视频组件。组件的属性可以实现视频的播放暂停,发送弹幕,获取视频所处位置等。
2.简单案例
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
src | string | 是 | 要播放视频的资源地址,支持网络路径、本地临时路径、云文件ID |
<video src="cloud://cloud1-0gq03z948cf60a2f.636c-cloud1-0gq03z948cf60a2f-1313616796/a2.mp4"></video>
3.自动循环播放
官方组件还提供了是否自动播放和是否循环播放的属性。通过设置autoplay
和loop
的值来实现相应功能。
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
autoplay | boolean | false | 否 | 是否自动播放 |
loop | boolean | false | 否 | 是否循环播放 |
<video src="cloud://cloud1-0gq03z948cf60a2f.636c-cloud1-0gq03z948cf60a2f-1313616796/a2.mp4"
autoplay="true" loop="true"></video>
4.容器适配
可以看到我们现在的视频是有黑边的这很影响视觉体验,那么如何去掉黑边呢,可以通过object-fit
属性来调整视频和video容器的大小关系。
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
object-fit | string | contain | 否 | 当视频大小与 video 容器大小不一致时,视频的表现形式 |
object-fit
属性 有如下取值:
合法值 | 说明 |
---|---|
contain | 包含 |
fill | 填充 |
cover | 覆盖 |
通过使用三种取值我发现取值为fill
时,视频会去通过拉伸去适配容器;而取值为cover
时会等比缩放视频,然后裁剪多余的部分去适配容器。
5.小窗模式
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
picture-in-picture-mode | string/Array | 否 | 设置小窗模式: push, pop,空字符串或通过数组形式设置多种模式(如: [“push”, “pop”]) |
video 小窗支持以下三种触发模式(在组件上设置 picture-in-picture-mode 属性):
- push 模式,即从当前页跳转至下一页时出现小窗(页面栈push)
- pop 模式,即离开当前页面时触发(页面栈pop)
- 以上两种路由行为均触发小窗
此外,小窗还支持以下特性:
- 小窗容器尺寸会根据原组件尺寸自动判断
- 点击小窗,用户会被导航回小窗对应的播放器页面
- 小窗出现后,用户可点击小窗右上角的关闭按钮或调用 context.exitPictureInPicture() 接口关闭小窗
当播放器进入小窗模式后,播放器所在页面处于 hide 状态(触发 onHide 生命周期),该页面不会被销毁。当小窗被关闭时,播放器所在页面会被 unload (触发 onUnload 生命周期)。
注意:在虚拟机上调试是无法看到小窗效果的,在手机真机上是可以的。
<!--pages/video/video.wxml-->
<video src="cloud://cloud1-0gq03z948cf60a2f.636c-cloud1-0gq03z948cf60a2f-1313616796/a2.mp4"
autoplay="true" loop="true" object-fit="cover" picture-in-picture-mode="push"></video>
<view class="container">
<button type="primary" size="mini" bindtap="gotoPrevideo">跳转到prevideo界面</button>
<button type="primary" size="mini" style="margin: 10px;" bindtap="gotoNextvideo">跳转到nextvideo界面</button>
</view>
6.视频弹幕案例
本案例针对video组件的实践应用场景编写了一个简单的发送视频弹幕的页面,其中使用到了播放视频相关的API函数:
可以看到我们弹幕中实现了静态的设置第几秒出现弹幕(绿色的弹幕)和按钮点击获取文本框里的文字然后输出到弹幕。
6.1wxml设计
具体怎么实现的呢,我来一一分说:首先在wxml
中我们还是定义了一个video容器,并为之取了一个id(id="myVideo"
),其次我们还用到了如下的属性:
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
danmu-list | Array. | 否 | 弹幕列表 | |
danmu-btn | boolean | false | 否 | 是否显示弹幕按钮,只在初始化时有效,不能动态变更 |
enable-danmu | boolean | false | 否 | 是否展示弹幕,只在初始化时有效,不能动态变更 |
除此之外我们还需要定义一个文本框来获取用户输入,和一个监听按钮来发送弹幕,代码如下:
<input bindblur="bindInputBlur" type="text" placeholder="输入弹幕内容" style="margin: 10px;"/>
<button type="primary" size="mini" bindtap="bindSendDanmu">发送弹幕</button>
6.2VideoContext类方法
VideoContext
实例,可通过 wx.createVideoContext
获取。
VideoContext
通过 id
跟一个 video
组件绑定,操作对应的video
组件。(这是为什么我们要在wxml中给video容器加一个id属性)
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady()
this.videoContext=wx.createVideoContext('myVideo')
,
在这里我们需要用到VideoContext.sendDanmu(Object data)
方法来发送弹幕
在这里我们定义两个监听函数bindInputBlur
和bindSendDanmu
bindInputBlur
:用来获取用户在文本框组件上输入的文字bindSendDanmu
:用来监听按钮发送弹幕
如此我们就大功告成了,还是很简单的,大家可以看看动图的效果。
bindInputBlur(e)
this.inputValue=e.detail.value;
,
bindSendDanmu()
this.videoContext.sendDanmu(
text:this.inputValue,
color:'#ff00ff'
)
,
6.2完整代码
<!--pages/video/video.wxml-->
<video id="myVideo" src="cloud://cloud1-0gq03z948cf60a2f.636c-cloud1-0gq03z948cf60a2f-1313616796/a2.mp4"
autoplay="true" loop="true" object-fit="cover" picture-in-picture-mode="push"
danmu-btn="true" danmu-list="danmuList" enable-danmu="true"></video>
<view class="container">
<input bindblur="bindInputBlur" type="text" placeholder="输入弹幕内容" style="margin: 10px;"/>
<button type="primary" size="mini" bindtap="bindSendDanmu">发送弹幕</button>
<button type="primary" size="mini" style="margin: 10px;" bindtap="gotoPrevideo">跳转到prevideo界面</button>
<button type="primary" size="mini" style="margin: 10px;" bindtap="gotoNextvideo">跳转到nextvideo界面</button>
</view>
// pages/video/video.js
Page(
/**
* 页面的初始数据
*/
inputValue:'',
data:
danmuList:[
text:'第1s出现的弹幕',color:'#ff0000',time:1,
text:'第3s出现的弹幕',color:'#00ff00',time:3,
]
,
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady()
this.videoContext=wx.createVideoContext('myVideo')
,
bindInputBlur(e)
this.inputValue=e.detail.value;
,
bindSendDanmu()
this.videoContext.sendDanmu(
text:this.inputValue,
color:'#ff00ff'
)
,
gotoPrevideo:function()
wx.navigateTo(
url: '../prevideo/prevideo',
)
,
gotoNextvideo:function()
wx.navigateTo(
url: '../nextvideo/nextvideo',
)
)
/* pages/video/video.wxss */
video
width: 100%;
height: 250px;
border-radius: 10px;
.container
display: flex;
text-align: center;
justify-items: center;
vertical-align: center;
7.小试牛刀
从零开始手写Tomcat的教程14节----服务器组件(Server)和服务组件(Service)
从零开始手写Tomcat的教程14节----服务器组件Server和服务组件Service
服务器组件
public interface Server
// ------------------------------------------------------------- Properties
/**
* Return descriptive information about this Server implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
*/
public String getInfo();
/**
* Return the global naming resources.
*/
public NamingResources getGlobalNamingResources();
/**
* Set the global naming resources.
*
* @param namingResources The new global naming resources
*/
public void setGlobalNamingResources
(NamingResources globalNamingResources);
/**
* Return the port number we listen to for shutdown commands.
*/
public int getPort();
/**
* Set the port number we listen to for shutdown commands.
*
* @param port The new port number
*/
public void setPort(int port);
/**
* Return the shutdown command string we are waiting for.
*/
public String getShutdown();
/**
* Set the shutdown command we are waiting for.
*
* @param shutdown The new shutdown command
*/
public void setShutdown(String shutdown);
// --------------------------------------------------------- Public Methods
/**
* Add a new Service to the set of defined Services.
*
* @param service The Service to be added
*/
public void addService(Service service);
/**
* Wait until a proper shutdown command is received, then return.
*/
public void await();
/**
* Return the specified Service (if it exists); otherwise return
* <code>null</code>.
*
* @param name Name of the Service to be returned
*/
public Service findService(String name);
/**
* Return the set of Services defined within this Server.
*/
public Service[] findServices();
/**
* Remove the specified Service from the set associated from this
* Server.
*
* @param service The Service to be removed
*/
public void removeService(Service service);
/**
* Invoke a pre-startup initialization. This is used to allow connectors
* to bind to restricted ports under Unix operating environments.
*
* @exception LifecycleException If this server was already initialized.
*/
public void initialize()
throws LifecycleException;
StandardServer类
initialize方法
/**
* Invoke a pre-startup initialization. This is used to allow connectors
* to bind to restricted ports under Unix operating environments.
*/
public void initialize()
throws LifecycleException
if (initialized)
throw new LifecycleException (
sm.getString("standardServer.initialize.initialized"));
initialized = true;
// Initialize our defined Services
for (int i = 0; i < services.length; i++)
services[i].initialize();
start方法
public void start() throws LifecycleException
// Validate and update our current component state
if (started)
throw new LifecycleException
(sm.getString("standardServer.start.started"));
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our defined Services
synchronized (services)
for (int i = 0; i < services.length; i++)
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).start();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
stop方法
public void stop() throws LifecycleException
// Validate and update our current component state
if (!started)
throw new LifecycleException
(sm.getString("standardServer.stop.notStarted"));
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
// Stop our defined Services
for (int i = 0; i < services.length; i++)
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).stop();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
await方法
public void await()
// Set up a server socket to wait on
ServerSocket serverSocket = null;
try
serverSocket =
new ServerSocket(port, 1,
InetAddress.getByName("127.0.0.1"));
catch (IOException e)
System.err.println("StandardServer.await: create[" + port
+ "]: " + e);
e.printStackTrace();
System.exit(1);
// Loop waiting for a connection and a valid command
while (true)
// Wait for the next connection
Socket socket = null;
InputStream stream = null;
try
socket = serverSocket.accept();
socket.setSoTimeout(10 * 1000); // Ten seconds
stream = socket.getInputStream();
catch (AccessControlException ace)
System.err.println("StandardServer.accept security exception: "
+ ace.getMessage());
continue;
catch (IOException e)
System.err.println("StandardServer.await: accept: " + e);
e.printStackTrace();
System.exit(1);
// Read a set of characters from the socket
StringBuffer command = new StringBuffer();
int expected = 1024; // Cut off to avoid DoS attack
while (expected < shutdown.length())
if (random == null)
random = new Random(System.currentTimeMillis());
expected += (random.nextInt() % 1024);
while (expected > 0)
int ch = -1;
try
ch = stream.read();
catch (IOException e)
System.err.println("StandardServer.await: read: " + e);
e.printStackTrace();
ch = -1;
if (ch < 32) // Control character or EOF terminates loop
break;
command.append((char) ch);
expected--;
// Close the socket now that we are done with it
try
socket.close();
catch (IOException e)
;
// Match against our command string
boolean match = command.toString().equals(shutdown);
if (match)
break;
else
System.err.println("StandardServer.await: Invalid command '" +
command.toString() + "' received");
// Close the server socket and return
try
serverSocket.close();
catch (IOException e)
;
Service接口
public interface Service
// ------------------------------------------------------------- Properties
/**
* Return the <code>Container</code> that handles requests for all
* <code>Connectors</code> associated with this Service.
*/
public Container getContainer();
/**
* Set the <code>Container</code> that handles requests for all
* <code>Connectors</code> associated with this Service.
*
* @param container The new Container
*/
public void setContainer(Container container);
/**
* Return descriptive information about this Service implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
*/
public String getInfo();
/**
* Return the name of this Service.
*/
public String getName();
/**
* Set the name of this Service.
*
* @param name The new service name
*/
public void setName(String name);
/**
* Return the <code>Server</code> with which we are associated (if any).
*/
public Server getServer();
/**
* Set the <code>Server</code> with which we are associated (if any).
*
* @param server The server that owns this Service
*/
public void setServer(Server server);
// --------------------------------------------------------- Public Methods
/**
* Add a new Connector to the set of defined Connectors, and associate it
* with this Service's Container.
*
* @param connector The Connector to be added
*/
public void addConnector(Connector connector);
/**
* Find and return the set of Connectors associated with this Service.
*/
public Connector[] findConnectors();
/**
* Remove the specified Connector from the set associated from this
* Service. The removed Connector will also be disassociated from our
* Container.
*
* @param connector The Connector to be removed
*/
public void removeConnector(Connector connector);
/**
* Invoke a pre-startup initialization. This is used to allow connectors
* to bind to restricted ports under Unix operating environments.
*
* @exception LifecycleException If this server was already initialized.
*/
public void initialize()
throws LifecycleException;
StandardService类
Connector和Container
public void setContainer(Container container)
Container oldContainer = this.container;
if ((oldContainer != null) && (oldContainer instanceof Engine))
((Engine) oldContainer).setService(null);
this.container = container;
if ((this.container != null) && (this.container instanceof Engine))
((Engine) this.container).setService(this);
if (started && (this.container != null) &&
(this.container instanceof Lifecycle))
try
((Lifecycle) this.container).start();
catch (LifecycleException e)
;
synchronized (connectors)
for (int i = 0; i < connectors.length; i++)
connectors[i].setContainer(this.container);
if (started && (oldContainer != null) &&
(oldContainer instanceof Lifecycle))
try
((Lifecycle) oldContainer).stop();
catch (LifecycleException e)
;
// Report this property change to interested listeners
support.firePropertyChange("container", oldContainer, this.container);
public void addConnector(Connector connector)
synchronized (connectors)
connector.setContainer(this.container);
connector.setService(this);
Connector results[] = new Connector[connectors.length + 1];
System.arraycopy(connectors, 0, results, 0, connectors.length);
results[connectors.length] = connector;
connectors = results;
if (initialized)
try
connector.initialize();
catch (LifecycleException e)
e.printStackTrace(System.err);
if (started && (connector instanceof Lifecycle))
try
((Lifecycle) connector).start();
catch (LifecycleException e)
;
// Report this property change to interested listeners
support.firePropertyChange("connector", null, connector);
public void removeConnector(Connector connector)
synchronized (connectors)
int j = -1;
for (int i = 0; i < connectors.length; i++)
if (connector == connectors[i])
j = i;
break;
if (j < 0)
return;
if (started && (connectors[j] instanceof Lifecycle))
try
((Lifecycle) connectors[j]).stop();
catch (LifecycleException e)
;
connectors[j].setContainer(null);
connector.setService(null);
int k = 0;
Connector results[] = new Connector[connectors.length - 1];
for (int i = 0; i < connectors.length; i++)
if (i != j)
results[k++] = connectors[i];
connectors = results;
// Report this property change to interested listeners
support.firePropertyChange("connector", connector, null);
与生命周期有关的方法
public void initialize()
throws LifecycleException
if (initialized)
throw new LifecycleException (
sm.getString("standardService.initialize.initialized"));
initialized = true;
// Initialize our defined Connectors
synchronized (connectors)
以上是关于『从零开始学小程序』媒体组件video组件的主要内容,如果未能解决你的问题,请参考以下文章