Hi guys,
I have managed to use HTTPProvider to create thumbnails/snapshots for the stream that is transcoded. But I wonder if it is possible for me to use/re-use/re-factor the code of CreateSnapshot to create the HTTPProvider for capturing snapshots of any stream ?
I have already taken a look at here, there was a comment of ripburn trying to create the HTTPProvider, I tried but it’s not working, here is his codes:
package com.test.wms.CreateSnapshot;
import java.io.*;
import com.wowza.util.FLVUtils;
import com.wowza.wms.amf.AMFPacket;
import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.http.*;
import com.wowza.wms.logging.*;
import com.wowza.wms.stream.IMediaStream;
import com.wowza.wms.vhost.*;
public class HTTPInterfaceTest extends HTTProvider2Base {
public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponse resp) {
if (!doHTTPAuthentication(vhost, req, resp))
return;
/*
* The variable appName must match whatever application name the live stream is broadcasting to.
*
* This provider must be called with a "stream-name" parameter specifying the stream name in the encoder
*
* i.e. http://127.0.0.1:8086/createsnapshot?stream-name=video
*
* The "stream-name" parameter can be changed by changing the streamParameterName value below.
*
* After the URL call (which can be done in the browser) it will either output the error or
* output the full path of the generated FLV file.
*/
OutputStream out = resp.getOutputStream();
String appName = "live";
String instanceName = IApplicationInstance.DEFAULT_APPINSTANCE_NAME;
String responseString = "";
String streamParameterName = "stream-name";
try
{
if (!vhost.applicationExists(appName)) {
throw new Exception("The folder for " + appName + " is missing in the applications folder.");
}
if (!vhost.getApplication("live").isAppInstanceLoaded(instanceName)) {
throw new Exception("The application " + appName + " is not running. You must broadcast to it before calling the snapshot creator.");
}
if (!req.getParameterNames().contains(streamParameterName)) {
throw new Exception("The parameter " + streamParameterName + " must be specified in the URL");
}
IApplicationInstance instance = vhost.getApplication(appName).getAppInstance(instanceName);
String streamName = req.getParameterMap().get(streamParameterName).get(0);
IMediaStream stream = instance.getStreams().getStream(streamName);
if (stream == null) {
throw new Exception("The stream name " + streamName + " is invalid. Does it match the value in the encoder?");
}
AMFPacket packet = stream.getLastKeyFrame();
if (packet == null) {
throw new Exception("Unable to grab screenshot. Try again shortly.");
}
//String flvFilename = "app_" + appName + "-stream_" + streamName + "-timecode_" + String.valueOf(packet.getAbsTimecode());
//File flvFile = stream.getStreamFileForWrite(flvFilename, null, null);
//String flvFilePath = flvFile.getAbsolutePath();
//flvFilePath = flvFilePath.substring(0, flvFilePath.length() - 4) + ".flv";
String flvFilename = streamName + "_" + packet.getAbsTimecode() + ".flv";
File flvFile = stream.getStreamFileForWrite(streamName, null, null);
String flvFilePath = flvFile.getPath().substring(0, flvFile.getPath().length()-4) + "_" + packet.getAbsTimecode() + ".flv";
Object lock = new Object();
String flvDetails = "";
synchronized(lock) {
BufferedOutputStream bufferedOut = new BufferedOutputStream(new FileOutputStream(new File(flvFilePath), false));
FLVUtils.writeHeader(bufferedOut, 0, null);
AMFPacket codecConfig = stream.getVideoCodecConfigPacket(packet.getAbsTimecode());
if (codecConfig != null) {
FLVUtils.writeChunk(bufferedOut, codecConfig.getDataBuffer(), codecConfig.getSize(), 0, (byte)codecConfig.getType());
switch(codecConfig.getType()) {
case IVHost.CONTENTTYPE_AUDIO:
flvDetails = "FLV codec info is audio. ";
break;
case IVHost.CONTENTTYPE_UKNOWN:
flvDetails = "FLV codec info is unknown. ";
break;
case IVHost.CONTENTTYPE_VIDEO:
flvDetails = "FLV codec info is video. ";
break;
default:
flvDetails = "FLV codec info is type " + String.valueOf(codecConfig.getType()) + ". ";
}
} else {
flvDetails = "FLV codec info is missing. ";
}
FLVUtils.writeChunk(bufferedOut, packet.getDataBuffer(), packet.getSize(), 0, (byte)packet.getType());
switch(packet.getType()) {
case IVHost.CONTENTTYPE_AUDIO:
flvDetails += "FLV packet info is audio. ";
break;
case IVHost.CONTENTTYPE_UKNOWN:
flvDetails += "FLV packet info is unknown. ";
break;
case IVHost.CONTENTTYPE_VIDEO:
flvDetails += "FLV packet info is video. ";
break;
default:
flvDetails += "FLV packet info is type " + String.valueOf(codecConfig.getType()) + ". ";
}
bufferedOut.close();
}
responseString = "Single-frame FLV saved successfully in " + flvFilePath + ". " + flvDetails;
byte[] outBytes = responseString.getBytes();
out.write(outBytes);
}
catch (IOException e) {
WMSLoggerFactory.getLogger(null).error("HTTPInterfaceTest IOException: " + e.toString());
}
catch (Exception e) {
WMSLoggerFactory.getLogger(null).error("HTTPInterfaceTest Exception: " + e.toString());
try {
responseString = e.toString();
byte[] outBytes = responseString.getBytes();
out.write(outBytes);
} catch (IOException e1) {
WMSLoggerFactory.getLogger(null).error("HTTPInterfaceTest IOException: " + e1.toString());
}
}
}
}
I have added the HTTPProvider as he commented
<HTTPProvider>
<BaseClass>com.test.wms.CreateSnapshot.HTTPInterfaceTest</BaseClass>
<RequestFilters>createsnapshot*</RequestFilters>
<AuthenticationMethod>none</AuthenticationMethod>
</HTTPProvider>
Basically I don’t want (actually I can’t) use the Flash Client to get the image, because I’m gonna build up a web service for receiving a command (record/stop/snapshot) and return the URI of the videos/images. I worked with WCF web services. If it’s possible to use the Flash Client to do this, please give me some hints, I really appreciate all of your suggestions
In additional, I was trying to work with Wowza IDE, but when I tried to start Wowza IDE, it showed bunch of errors (I started Wowza IDE after turning of all the Wowza Streaming Engine services). I don’t have Java installed, just the JRE, is it the cause of this ?
Best.
Anh-Dzung