Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: [Livestream] How can we create a snapshot of 1 video stream through HTTPProvider

  1. #1
    Join Date
    Apr 2014
    Posts
    18

    Lightbulb [Livestream] How can we create a snapshot of 1 video stream through HTTPProvider

    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
    Last edited by anhdung; 04-17-2014 at 02:32 AM.

  2. #2
    Join Date
    Dec 2007
    Posts
    22,013

    Default

    I tried your HTTPProvider, and it worked great.

    But I found that it only worked with VP6 video, not h.264, which I think is a limitation of the module you started with.

    Richard

  3. #3
    Join Date
    Apr 2014
    Posts
    18

    Default

    Hi Richard,
    Thanks for your response, it helps me a lot.
    yes, I just tried with the h.264 video. I don't know if there is another module which is suitable for this video stream.
    Regards
    AD

  4. #4
    Join Date
    Dec 2007
    Posts
    22,013

    Default

    I will see what I can find out about extending it. There isn't as much VP6 and Spark video around anymore.

    Richard

  5. #5
    Join Date
    Apr 2014
    Posts
    18

    Default

    Quote Originally Posted by rrlanham View Post
    I will see what I can find out about extending it. There isn't as much VP6 and Spark video around anymore.

    Richard
    It will be a great deal if you can manage to get some snapshot through HTTP Provider, with it, I will have all basic functions I need from Wowza!

    Additionally, when I tried to do some outputs (html format) to test how the code flows, if I don't have the exception, I always got the
    Wowza Streaming Engine 4 Trial Edition (Expires: sept. 19, 2014) 4.0.3 build10989
    result, although after the checking code (of streamname, ...), I tried to output the hello word phrase in the web but fail. Is that greetings is the default return value for wowza when we call http provider stuff ?

    Regards
    Last edited by anhdung; 04-18-2014 at 05:15 AM.

  6. #6

    Default

    Hi,

    The trick with h.264 is to write the same packet twice to the flv.

    				AMFPacket codecConfig = stream.getVideoCodecConfigPacket(packet.getAbsTimecode());
    				if (codecConfig != null)
    					FLVUtils.writeChunk(bufferedOut, codecConfig.getDataBuffer(), codecConfig.getSize(), 0, (byte)codecConfig.getType());
    
    				FLVUtils.writeChunk(bufferedOut, packet.getDataBuffer(), packet.getSize(), 0, (byte)packet.getType());
    				FLVUtils.writeChunk(bufferedOut, packet.getDataBuffer(), packet.getSize(), 100, (byte)packet.getType());
    Not sure why it works , it just does.

    Roger.

  7. #7
    Join Date
    Apr 2014
    Posts
    18

    Default

    Quote Originally Posted by roger_l View Post
    Hi,

    The trick with h.264 is to write the same packet twice to the flv.

    				AMFPacket codecConfig = stream.getVideoCodecConfigPacket(packet.getAbsTimecode());
    				if (codecConfig != null)
    					FLVUtils.writeChunk(bufferedOut, codecConfig.getDataBuffer(), codecConfig.getSize(), 0, (byte)codecConfig.getType());
    
    				FLVUtils.writeChunk(bufferedOut, packet.getDataBuffer(), packet.getSize(), 0, (byte)packet.getType());
    				FLVUtils.writeChunk(bufferedOut, packet.getDataBuffer(), packet.getSize(), 100, (byte)packet.getType());
    Not sure why it works , it just does.

    Roger.
    Hi Roger,
    Thanks for your help, but when I tried to add your codes into the current work, there's still now flv image appears, all I had was the text "Wowza Streaming Engine 4 Trial Edition (Expires: sept. 19, 2014) 4.0.3 build10989"
    Here are my codes so far.

    	public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponse resp) {
    		if (!doHTTPAuthentication(vhost, req, resp))
    			return;
    
    		
    		/*
    		String helloStr1 = "Hello world";
    		String retStr1 = "<html><head><title>" + helloStr1
    				+ "</title></head><body>" + helloStr1 + "</body></html>";
    
    		try {
    			OutputStream out = resp.getOutputStream();
    			byte[] outBytes = retStr1.getBytes();
    			out.write(outBytes);
    		} catch (Exception e) {
    			WMSLoggerFactory.getLogger(null).error(
    					"MyHTTPProvider: " + e.toString());
    		}
    		*/
    
    		/*
    		 * 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");				
    			}
    				
    			String helloStr1 = "Instance ok!";
    			String retStr1 = "<html><head><title>" + helloStr1
    					+ "</title></head><body>" + helloStr1 + "</body></html>";
    
    			try {
    				//OutputStream out = resp.getOutputStream();
    				byte[] outBytes = retStr1.getBytes();
    				out.write(outBytes);
    			} catch (Exception e) {
    				WMSLoggerFactory.getLogger(null).error(
    						"MyHTTPProvider: " + e.toString());
    			}
    			
    			
    			IApplicationInstance instance = vhost.getApplication(appName).getAppInstance(instanceName);
    			
    						
    			
    			String streamName = req.getParameterMap().get(streamParameterName).get(0);			
    			IMediaStream stream = instance.getStreams().getStream(streamName);
    			
    			String helloStr = "Hello World! You are trying to get snapshot from stream: " + streamParameterName;
    			String retStr = "<html><head><title>" + helloStr
    					+ "</title></head><body>" + helloStr + "</body></html>";
    
    			try {
    				OutputStream output = resp.getOutputStream();
    				byte[] outBytes = retStr.getBytes();
    				output.write(outBytes);
    			} catch (Exception e) {
    				WMSLoggerFactory.getLogger(null).error(
    						"MyHTTPProvider: " + e.toString());
    			}
    			
    			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());
    				FLVUtils.writeChunk(bufferedOut, packet.getDataBuffer(), packet.getSize(), 100, (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());
    			}
    		}
    	}
    Regards,
    Anh-dzung

  8. #8

    Default

    Quote Originally Posted by anhdung View Post
    all I had was the text "Wowza Streaming Engine 4 Trial Edition (Expires: sept. 19, 2014) 4.0.3 build10989"
    The reason you will be getting this response is because your HttpProvider is not configured properly in the VHost.xml Hostport configuration.

    You need to edit the VHost.xml and add your HTTPProvider.

    Roger.

  9. #9
    Join Date
    Apr 2014
    Posts
    18

    Default

    Quote Originally Posted by roger_l View Post
    The reason you will be getting this response is because your HttpProvider is not configured properly in the VHost.xml Hostport configuration.

    You need to edit the VHost.xml and add your HTTPProvider.

    Roger.
    Ok, I have registered but I put the * in front, that's why it didn't work out. I have to change into
    <HTTPProvider> 
        <BaseClass>com.mycompany.wms.module.MyHTTPProvider</BaseClass> 
        <RequestFilters>myhttpprovider*</RequestFilters> 
        <AuthenticationMethod>none</AuthenticationMethod> 
    </HTTPProvider>
    Now it works like charm. Many thanks for your help Roger!!! It would be great for other guys who want to do the same with H264 to know this if you can update it in the CreateSnapshot as well

    Regards,
    Anh-Dzung

  10. #10

    Default

    Quote Originally Posted by anhdung View Post
    Now it works like charm. Many thanks for your help Roger!!! It would be great for other guys who want to do the same with H264 to know this if you can update it in the CreateSnapshot as well
    Good to hear it is working. I have added a note to update the CreateSnapshot module for the next release of the collection.

    Roger.

Page 1 of 2 12 LastLast

Similar Threads

  1. Snapshot a transcoded video
    By anhdung in forum Live Streaming and Encoders
    Replies: 6
    Last Post: 05-28-2014, 10:46 AM
  2. Replies: 4
    Last Post: 10-09-2013, 07:00 AM
  3. Livestream video convert to Audio stream
    By Terry Mitchell in forum General Forum
    Replies: 1
    Last Post: 07-09-2013, 07:40 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •