Results 1 to 5 of 5

Thread: Can't get live captioning and/or metadata working

  1. #1
    Join Date
    Aug 2014
    Posts
    5

    Question Can't get live captioning and/or metadata working

    We are trying to setup a scenario where we use Wowza to stream live video to clients, but inject captioning and metadata into the stream from an external source at various points in time. As such I have implemented the following module following guides found here:

    public class CaptioningInjectionModule extends HTTProvider2Base {
    
    	private IServer server;
    
    	public void onServerInit(IServer server) {
    		this.server = server;
    	}
    
    	@Override
    	public void onHTTPRequest(IVHost ivHost, IHTTPRequest ihttpRequest, IHTTPResponse ihttpResponse) {
    		String appName = ihttpRequest.getParameter("appName");
    		String appInstanceName = ihttpRequest.getParameter("appInstanceName");
    		appInstanceName = appInstanceName == null ? "_definst_" : appInstanceName;
    		String streamName = ihttpRequest.getParameter("streamName");
    		BufferedReader reader = new BufferedReader(new InputStreamReader(ihttpRequest.getInputStream()));
    		String text = null;
    		try {
    			text = reader.readLine();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		String language = ihttpRequest.getParameter("language");
    		String trackId = ihttpRequest.getParameter("trackId");
    
    		IMediaStream stream = ivHost.getApplication(appName).getAppInstance(appInstanceName).getStreams()
    				.getStream(streamName);
    
    		setCaption(stream, text, language, trackId);
    	}
    
    	private void setCaption(final IMediaStream stream, final String text, final String language, final String trackId) {
    		if (stream != null) {
    			AMFDataObj data = new AMFDataObj();
    			data.put("text", new AMFDataItem(text));
    			data.put("language", new AMFDataItem(language));
    			data.put("trackid", new AMFDataItem(trackId));
    			stream.sendDirect("onTextData", data);
    			((MediaStream) stream).processSendDirectMessages();
    		}
    	}
    }
    and

    public class MetadataInjectionModule extends HTTProvider2Base {
    
    	private IServer server;
    
    	public void onServerInit(IServer server) {
    		this.server = server;
    	}
    
    	@Override
    	public void onHTTPRequest(IVHost ivHost, IHTTPRequest ihttpRequest, IHTTPResponse ihttpResponse) {
    		String appName = ihttpRequest.getParameter("appName");
    		String appInstanceName = ihttpRequest.getParameter("appInstanceName");
    		appInstanceName = appInstanceName == null ? "_definst_" : appInstanceName;
    		String streamName = ihttpRequest.getParameter("streamName");
    		BufferedReader reader = new BufferedReader(new InputStreamReader(ihttpRequest.getInputStream()));
    		StringBuilder data = new StringBuilder();
    		try {
    			String line;
    			while((line = reader.readLine()) != null) {
    				data.append(line);
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    
    		IMediaStream stream = ivHost.getApplication(appName).getAppInstance(appInstanceName).getStreams()
    				.getStream(streamName);
    
    		injectMetadata(stream, data.toString());
    	}
    
    	private void injectMetadata(final IMediaStream stream, final String data) {
    		if (stream != null) {
    			AMFDataList amfList = new AMFDataList();
    
    			amfList.add(new AMFDataItem("@setDataFrame"));
    			amfList.add(new AMFDataItem("onMetaData"));
    
    			AMFDataMixedArray metaData = new AMFDataMixedArray();
    
    			metaData.put("param1", data);
    			metaData.put("param2", new AMFDataItem("data2"));
    
    			amfList.add(metaData);
    
    			synchronized (stream) {
    				byte[] dataData = amfList.serialize();
    				int size = dataData.length;
    				long timecode = Math.max(stream.getAudioTC(), stream.getVideoTC());
    				stream.setDataTC(timecode);
    				stream.setDataSize(size);
    				stream.startDataPacket();
    				stream.addDataData(dataData, 0, size);
    			}
    		}
    	}
    }
    and set these up in my VHost.xml file:

    <HTTPProvider>
    	<BaseClass>gamesys.wowza.server.modules.CaptioningInjectionModule</BaseClass>
    	<RequestFilters>caption*</RequestFilters>
    	<AuthenticationMethod>none</AuthenticationMethod>
    </HTTPProvider>
    <HTTPProvider>
    	<BaseClass>gamesys.wowza.server.modules.MetadataInjectionModule</BaseClass>
    	<RequestFilters>metadata*</RequestFilters>
    	<AuthenticationMethod>none</AuthenticationMethod>
    </HTTPProvider>
    Both endpoints work and I don't see any exceptions in the Wowza server logs. My question is how can I get hold of this data on the client. I have tried various players like flowplayer and jwplayer by binding to their onMetadata or onCuepoint etc. events but I never seem to get anything come through. Is there a stage in the middle I am missing?

  2. #2

    Default

    Hi,

    Apologies if you have seen this already or if it's not directly relevant but we do have an article covering live closed captioning which also includes a sample module including source for writing live captions using AMF onTextData events, which can be used with Flowplayer, JW Player etc.


    Paul

  3. #3
    Join Date
    Aug 2014
    Posts
    5

    Default

    Quote Originally Posted by Paul_S View Post
    Hi,

    Apologies if you have seen this already or if it's not directly relevant but we do have an article covering live closed captioning which also includes a sample module including source for writing live captions using AMF onTextData events, which can be used with Flowplayer, JW Player etc.


    Paul
    Thanks Paul,

    This section: http://www.wowza.com/forums/content.php?447#ontextdata resolved my issue. Are there similar sample modules etc. for streaming live metadata?

  4. #4

    Default

    Hi James,

    Good to hear you're progressing. We've the following article covering injecting metadata into RTMP (or HLS if converted to id3 tags). There may be others more relevant to you. I'd also suggest a look at our articles list or search the forum. I think these questions do pop up now and again.

    Paul

  5. #5
    Join Date
    Aug 2014
    Posts
    5

    Default

    Hi Paul,

    I did have a read of the article you posted. I am just getting confused as some of the articles seem to be contradictory (although maybe it is my lack of understanding) i.e.
    This article suggests that captions be injected by calling stream.sendDirect("onTextData"...) and metadata be injected by calling stream.addDataData(...)
    http://www.wowza.com/forums/content....point-MetaData

    But then this article is talking about converting "onTextData" events to ID3 metadata, even though the prior one says to use this for captioning:
    http://www.wowza.com/forums/content....ple-HLS-stream

    Maybe there is more than one way to do this but as a novice its quite confusing.

Similar Threads

  1. Live Closed Captioning solution for multiple platforms
    By gavram in forum Closed Captioning
    Replies: 1
    Last Post: 01-30-2014, 10:53 AM
  2. Live 608/708 captioning
    By markeast in forum Live Streaming and Encoder Discussion
    Replies: 6
    Last Post: 08-29-2012, 07:15 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
  •