Skip to content

Instantly share code, notes, and snippets.

@mondain
Last active August 30, 2016 19:04
Show Gist options
  • Save mondain/fd5e39a9b1606aa0b23ece22b77d16ae to your computer and use it in GitHub Desktop.
Save mondain/fd5e39a9b1606aa0b23ece22b77d16ae to your computer and use it in GitHub Desktop.
Info for REDSUPPORT-352 ticket

Properties / statistics requested:

  • 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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment