private static List<Double> extractStreamTrackStat(List<RTCRtpStreamStats> streams, StatEnum stat) {
    List<Double> result = new ArrayList<>();
    for (RTCRtpStreamStats stream : streams) {
      switch (stat) {
        case RECEIVED_BITRATE:
        case SENT_BITRATE:
        case BYTES:
          if (stream instanceof RTCReceivedRtpStreamStats) {
            result.add(((RTCReceivedRtpStreamStats)stream).getBytesReceived());
          } else {
            if (stream instanceof RTCSentRtpStreamStats) {
              result.add(((RTCSentRtpStreamStats) stream).getBytesSent());
            }
          }
          break;
        case PACKETS:
          if (stream instanceof RTCInboundRtpStreamStats) {
            result.add(((RTCInboundRtpStreamStats)stream).getPacketsReceived());
          } else {
            result.add(((RTCSentRtpStreamStats)stream).getPacketsSent());
          }
          break;
        case PACKETS_LOST:
        case AVG_PACKETS_LOST:
          result.add(((RTCReceivedRtpStreamStats)stream).getPacketsLost());
          break;
        case PACKETS_DISCARDED:
          result.add(((RTCReceivedRtpStreamStats)stream).getPacketsDiscarded());
          break;
        case JITTER:
        case AVG_JITTER:
          if (stream.getKind().equals("audio") && stream instanceof RTCInboundRtpStreamStats) {
            result.add(((RTCReceivedRtpStreamStats)stream).getJitter());
          }
          break;
        case AUDIO_LEVEL:
        case AVG_AUDIO_LEVEL:
          if (stream.getKind().equals("audio")) {
            if (stream instanceof RTCInboundRtpStreamStats) {
              result.add(((RTCInboundRtpStreamStats)stream).getAudioLevel());
            }
          }
          break;
        case FRAME:
        case TOTAL_FRAME_RECEIVED:
        case TOTAL_FRAME_SENT:
          if (stream.getKind().equals("video")) {
            if (stream instanceof RTCInboundRtpStreamStats) {
              result.add(((RTCInboundRtpStreamStats)stream).getFramesReceived() == -1
                  ? ((RTCInboundRtpStreamStats)stream).getFramesDecoded()
                  : ((RTCInboundRtpStreamStats)stream).getFramesReceived());
            } else {
              result.add(((RTCOutboundRtpStreamStats)stream).getFramesSent() == -1
                  ? ((RTCOutboundRtpStreamStats)stream).getFramesEncoded()
                  : ((RTCOutboundRtpStreamStats)stream).getFramesSent());
            }
          }
          break;
        case FRAME_RATE:
          if (stream.getKind().equals("video")) {
            //            todo
            if (stream instanceof RTCOutboundRtpStreamStats) {
              result.add(((RTCOutboundRtpStreamStats) stream).getFramesPerSecond());
            }
          }
          break;
//        case AVG_FRAME_RATE_DECODED:
        case FRAME_DECODED:
          if (stream.getKind().equals("video")) {
            //            todo
            if (stream instanceof RTCInboundRtpStreamStats) {
              result.add(((RTCInboundRtpStreamStats)stream).getFramesDecoded());
            }
          }
          break;
        case FRAME_DROPPED:
          if (stream.getKind().equals("video")) {
            result.add(((RTCInboundRtpStreamStats)stream).getFramesDropped());
          }
          break;
          // not applicable
//        case FRAME_CORRUPTED:
//          if (stream.isVideo()) {
//            result.add(stream.getTrack() == null ? -1.0 : stream.getTrack().getFramesCorrupted());
//          }
//          break;
        default:
          logger.error("Wrong place to look for :" + stat.toString());
          break;
      }
    }
    if (result.isEmpty()) {
      logger.debug("There seems to be no values available for " + stat + ". " +
        "Please verify that you're trying to extract from the right streams/tracks (inbound/outbound and/or audio/video)");
    }
    if (containOnly(result, -1.0)) {
      logger.debug("There seems to be no track available for " + stat + ". " +
        "Please verify that the media track stats are included in the provided stats.");
    }

    return result;
  }
@param statArray     array of stats provided from getStats()
@param fullyDetailed true if the detailed arrays of specific stat values are to be added to the summary

@return  the stat summary : (Sample stats on Chrome 74)
    "Starting Timestamp": "2019-06-28 162729",
    "Ending Timestamp": "2019-06-28 162740",
    "Total Inbound Bytes Received (Bytes)": 642114,
    "Total Inbound Audio Bytes Received (Bytes)": 114190,
    "Total Inbound Video Bytes Received (Bytes)": 527924,
    "Total Outbound Bytes Sent (Bytes)": 644136,
    "Total Outbound Audio Bytes Sent (Bytes)": 114371,
    "Total Outbound Video Bytes Sent (Bytes)": 529765,
    "Total Round Trip Time (ms)": 0.0,
    "Average Current Round Trip Time (ms)": 0.0,
    "inbound": {
            "audio": [
            {
                "streamId": "RTCInboundRTPAudioStream_3333556480",
                "Total Bytes Received (Bytes)": "34997",
                "Average Received Bitrate (kbps)": "3071",
                "Total Packets Received": "585",
                "Average Audio Level (dB)": "0",
                "Total Packets Lost": 0,
                "Packets Lost (%)": "0",
                "Packets Discarded (%)": "0",
                "Average Audio Jitter (ms)": "0"
            }
        ],
        "video": [
            {
                "streamId": "RTCInboundRTPVideoStream_3131213379",
                "Total Bytes Received (Bytes)": "1031833",
                "Average Received Bitrate (kbps)": "95078",
                "Total Packets Received": "1006",
                "Frames Received": "234",
                "Average Frame Rate (fps)": "0",
                "Total Packets Lost": 0,
                "Packets Lost (%)": "0",
                "Packets Discarded (%)": "0"
            }
        ]
    },
    "outbound": {
        "audio": [ same as inbound stats ],
        "video": [ same as inbound stats ]
    }
KITE-Framework/src/main/java/org/webrtc/kite/stats/StatsUtils.java