Grabbing Stream Information

QUESTION:

Can I grab the following stream statistics:

  • stream start time (unix timestamp)
  • stream end time (unix timestamp)
  • broadcaster user agent
  • video codec
  • audio codec
  • video size (width and height)
  • FPS
  • total bitrate (bits per second)
  • video bitrate (bits per second)
  • audio bitrate (bits per second)
  • keyframe interval

 

ANSWER:

Many of these stats have to be calculated and many are not collected nor calculated on the server. Below I will detail how to access what is available.

To get the start time when starting publishing in the streamBroadcastStart(IBroadcastStream stream) method

long startTime = ((ClientBroadcastStream) stream).getCreationTime();

A streams end time is not stored and I would suggest collecting that instant using the streamBroadcastClose(IBroadcastStream stream) method in your application adapter:

long endTime = System.currentTimeMillis();

A broadcasters user-agent is available via the IConnection which represents the current connection and may be accessed in any of the application adapter methods like so (ApplicationAdapter.connect() shown):

@Override
public boolean connect(IConnection conn, IScope scope, Object[] params) {
    Map<String, Object> connParameters = conn.getConnectParams()
    String userAgent = connParameters.get("flashVer").toString();
    return super.connect(conn, scope, params);
}

Connection parameters output:

{app=issues/test, tcUrl=rtmp://localhost/issues/test, audioCodecs=3575.0, path=issues/test, capabilities=239.0, swfUrl=http://localhost:5080/demos/publisher.swf, videoFunction=1.0, flashVer=LNX 22,0,0,209, videoCodecs=252.0, pageUrl=http://localhost:5080/demos/publisher.html, objectEncoding=0.0, fpad=false} 

The codec ids may be accessed via these methods:

IStreamCodecInfo info = ((ClientBroadcastStream) stream).getCodecInfo()
String audioCodec = info.getAudioCodecName();
String videoCodec = info.getVideoCodecName();

Please be aware that if the video codec is not AVC/h.264 (id=7) or the audio codec is not AAC (id=10), the values may be null and to get the missing codec, you'd need to observe the AudioData or VideoData packets and pull the codec id's from them and match the values: AudioCodec enumeration:

    PCM((byte) 0),
    ADPCM((byte) 0x01),
    MP3((byte) 0x02),
    PCM_LE((byte) 0x03),
    NELLY_MOSER_16K((byte) 0x04),
    NELLY_MOSER_8K((byte) 0x05),
    NELLY_MOSER((byte) 0x06),
    PCM_ALAW((byte) 0x07),
    PCM_MULAW((byte) 0x08),
    RESERVED((byte) 0x09),
    AAC((byte) 0x0a),
    SPEEX((byte) 0x0b),
    MP3_8K((byte) 0x0e),
    DEVICE_SPECIFIC((byte) 0x0f);

VideoCodec enumeration:

	JPEG((byte) 0x01), 
	H263((byte) 0x02),
	SCREEN_VIDEO((byte) 0x03),
	VP6((byte) 0x04),
	VP6a((byte) 0x05),
	SCREEN_VIDEO2((byte) 0x06),
	AVC((byte) 0x07);

To access metadata:

Map<Object,Object> metaData = null;
Notify notify = ((ClientBroadcastStream) stream).getMetaData();
Input reader = new Input(notify.getData());
// string datatype
reader.readDataType();
String method = reader.readString();
if (method.equals("onMetaData")) {
  // object type
  reader.readDataType();
  metaData = (Map<Object,Object>) reader.readMap();
  // now the map may be queried for key / value pairs such as width, height, fps, samplerate, audiocodecid, videocodecid etc
  int width = metaData.containsKey("width") ? ((Number) metaData.get("width")).intValue();
}

Also note that if your publishing client doesn't send metadata properties such as "fps", they won't be available in the map.

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.