一、HTTP Provider
你可以用一个已经内建的,位于管理端口8086上的HTTP接口来从正在运行中的Wowza transcoder获得一个位图。Http URL格式如下:
http://[wowza-ip-address]:8086/transcoderthumbnail?application=[application-name]&streamname=[stream-name]&format=[jpeg or png]&size=[widthxheight]其中:
- [wowza-ip-address]: 运行Wowza Server的服务器IP地址
- application-name: 应用名
- stream-name: 输入流的stream name. 不要用转码后的输出流的名字或StreamNameGroup的名字.
- format: 图片的格式:jpeg 或 png
- size: 截图的大小.如果没有设置,则会按一帧图像的完整大小返回
要使用这个HTTP服务,请用文本编辑器打开[install-dir]/conf/VHost.xml文件,将com.wowza.wms.transcoder.httpprovider.HTTPTranscoderThumbnail 中的 AuthenticationMethod 设置为: none。这样将关闭基于用户名和密码的认证。
接下来, 对Wowza Server进行配置,以对一个输入流进行转码。如何对直播流配置转码,请阅读如何为一个直播流配置转码?
在下面的例子中, 假定我们要转码的流为myStream,应用名为live. 要获得这个实时流的当前截图,请在WEB浏览器上访问以下URL:
http://[wowza-ip-address]:8086/transcoderthumbnail?application=live&streamname=myStream&format=jpeg&size=320x240注意: 这个URL是区分大小写的。 日志
每一次请求截图时,你都会在[install-dir]/logs/wowzamediaserver_access.log中看到一个log消息:
comment server INFO 200 - HTTPTranscoderThumbnail#GrabResult.onGrabFrame[live/_definst_/myStream]: Image result: format:jpeg size:320x240 timecode:107633
二、服务端 API
下面是一段代码例子,建立了莪一个名为grabFrame([stream-name])的方法,可供远程调用,获得实时流的当前截图:
package com.wowza.wms.plugin.test.module; import java.awt.image.*; import javax.imageio.*; import java.io.*; import com.wowza.wms.amf.*; import com.wowza.wms.client.*; import com.wowza.wms.request.*; import com.wowza.wms.module.*; import com.wowza.wms.application.*; import com.wowza.wms.stream.*; import com.wowza.wms.transcoder.model.*; import com.wowza.wms.transcoder.util.*; public class ModuleTestTranscoderFrameGrab extends ModuleBase { private IApplicationInstance appInstance = null; class GrabResult implements ITranscoderFrameGrabResult { public void onGrabFrame(TranscoderNativeVideoFrame videoFrame) { BufferedImage image = TranscoderStreamUtils.nativeImageToBufferedImage(videoFrame); if (image != null) { getLogger().info("ModuleTestTranscoderFrameGrab#GrabResult.onGrabFrame: "+image.getWidth()+"x"+image.getHeight()); String storageDir = appInstance.getStreamStoragePath(); File pngFile = new File(storageDir+"/thumbnail.png"); File jpgFile = new File(storageDir+"/thumbnail.jpg"); try { if (pngFile.exists()) pngFile.delete(); ImageIO.write(image, "png", pngFile); getLogger().info("ModuleTestTranscoderFrameGrab#GrabResult.onGrabFrame: Save image: "+pngFile); } catch(Exception e) { getLogger().error("ModuleTestTranscoderFrameGrab.grabFrame: File write error: "+pngFile); } try { if (jpgFile.exists()) jpgFile.delete(); ImageIO.write(image, "jpg", jpgFile); getLogger().info("ModuleTestTranscoderFrameGrab#GrabResult.onGrabFrame: Save image: "+jpgFile); } catch(Exception e) { getLogger().error("ModuleTestTranscoderFrameGrab.grabFrame: File write error: "+jpgFile); } } } } public void onAppStart(IApplicationInstance appInstance) { getLogger().info("ModuleTestTranscoderFrameGrab.onAppStart["+appInstance.getContextStr()+"]"); this.appInstance = appInstance; } public void grabFrame(IClient client, RequestFunction function, AMFDataList params) { getLogger().info("ModuleTestTranscoderFrameGrab.grabFrame"); while(true) { String streamName = params.getString(PARAM1); if (streamName == null) { getLogger().warn("ModuleTestTranscoderFrameGrab.grabFrame: No streamName"); break; } IApplicationInstance appInstance = client.getAppInstance(); if (appInstance == null) { getLogger().warn("ModuleTestTranscoderFrameGrab.grabFrame: No appInstance"); break; } IMediaStream stream = appInstance.getStreams().getStream(streamName); if (stream == null) { getLogger().warn("ModuleTestTranscoderFrameGrab.grabFrame: No stream"); break; } LiveStreamTranscoder liveStreamTranscoder = (LiveStreamTranscoder)stream.getLiveStreamTranscoder("transcoder"); if (liveStreamTranscoder == null) { getLogger().warn("ModuleTestTranscoderFrameGrab.grabFrame: No liveStreamTranscoder"); break; } TranscoderStream transcodingStream = liveStreamTranscoder.getTranscodingStream(); if (transcodingStream == null) { getLogger().warn("ModuleTestTranscoderFrameGrab.grabFrame: No transcodingStream"); break; } TranscoderStreamSourceVideo sourceVideo = transcodingStream.getSource().getVideo(); if (sourceVideo == null) { getLogger().warn("ModuleTestTranscoderFrameGrab.grabFrame: No sourceVideo"); break; } getLogger().info("ModuleTestTranscoderFrameGrab.grabFrame: Call grabFrame"); sourceVideo.grabFrame(new GrabResult(), 426, 240); break; } } }