syntax = "proto3";

package twitch.video.usher;
option go_package = "code.justin.tv/video/usherapi/rpc/usher";

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";

// The channel_properties service provides APIs for retrieving complex property
// data about encoded video streams, like the formats available, gop sizes, etc.
//
// Most of the API code can be found here:
// https://git-aws.internal.justin.tv/video/usher/blob/8625aaf2dfad2462cf7b570a1d6bc9a8fd2e98b8/api/channel_properties.py

message ChannelProperties {
  // id appears to be rarely used, instead channel properties entries are
  // referenced by channel_id or channel_name almost exclusively
  int64 id = 1 [json_name = "id"];

  // channel_id is the twitch channel id for this stream
  int64 channel_id = 2 [json_name = "channel_id"];

  // channel is the twitch channel name for this stream
  string channel = 3 [json_name = "channel"];

  // customer_id is the LVS customer id for this stream, always set to "twitch"
  // for Twitch streams
  string customer_id = 4 [json_name = "customer_id"];

  // content_id is the LVS content id for this stream, always set to a stringified
  // channel_id for Twitch streams
  string content_id = 5 [json_name = "customer_id"];

  // video_codec is the video codec of this channel
  //
  // Looks like:
  //   "avc1.64002A"
  string video_codec = 6 [json_name = "video_codec"];

  // audio_codec is the audio codec of this channel
  //
  // Looks like:
  //   "mp4a.40.2"
  string audio_codec = 7 [json_name = "audio_codec"];

  // avc_profile is the AVC profile of this stream
  //
  // Looks like:
  //   "High"
  string avc_profile = 8 [json_name = "avc_profile"];

  // target_fps apears to frequently be unset, unclear if this has meaning
  double target_fps = 9 [json_name = "target_fps"];

  // vfr appears to frequently be unset, the acronym likely stands for variable
  // frame rate
  // TODO: document the schema of this field's value if anyone can find it
  bool vfr = 10 [json_name = "vfr"];

  // avc_level is the AVC level string for this channel
  //
  // Looks like:
  //   "42"
  string avc_level = 11 [json_name = "avc_level"];

  // channels is the number of audio channels this stream has
  int32 channels = 12 [json_name = "channels"];

  // width_pixels is the source video width in pixels
  int32 width_pixels = 13 [json_name = "width"];

  // height_pixels is the source video height in pixels
  int32 height_pixels = 14 [json_name = "height"];

  // sample_rate is the audio sample rate
  double sample_rate_hz = 15 [json_name = "sample_rate"];

  // idr_aligned_ratio NEEDS DOCUMENTATION
  double idr_aligned_ratio = 16 [json_name = "idr_aligned_percent"];

  // average_fps is the average framerate of this stream
  double average_fps = 17 [json_name = "average_fps"];

  // average_kbps is the average bitrate of this stream
  double average_kbps = 18 [json_name = "average_kbps"];

  // max_kbps is the maximum observed bitrate of this stream
  double max_kbps = 19 [json_name = "max_kbps"];

  // max_idr_delta_millis is the largest time seen between keyframes in milliseconds
  double max_idr_delta_millis = 20 [json_name = "max_idr_delta"];
}

message ChannelPropertiesUpdateRequest {
  int64 channel_properties_id = 1;
  ChannelPropertiesUpdate update = 2;
}

message ChannelPropertiesShowRequest {
  string channel = 1;
}

message ChannelPropertiesUpdate {
  google.protobuf.StringValue video_codec          = 1  [json_name = "video_codec"];
  google.protobuf.StringValue audio_codec          = 2  [json_name = "audio_codec"];
  google.protobuf.StringValue avc_profile          = 3  [json_name = "avc_profile"];
  google.protobuf.DoubleValue target_fps           = 4  [json_name = "target_fps"];
  google.protobuf.BoolValue   vfr                  = 5  [json_name = "vfr"];
  google.protobuf.StringValue avc_level            = 6  [json_name = "avc_level"];
  google.protobuf.Int32Value  channels             = 7  [json_name = "channels"];
  google.protobuf.Int32Value  width_pixels         = 8  [json_name = "width"];
  google.protobuf.Int32Value  height_pixels        = 9  [json_name = "height"];
  google.protobuf.DoubleValue sample_rate_hz       = 10 [json_name = "sample_rate"];
  google.protobuf.DoubleValue idr_aligned_ratio    = 11 [json_name = "idr_aligned_percent"];
  google.protobuf.DoubleValue average_fps          = 12 [json_name = "average_fps"];
  google.protobuf.DoubleValue average_kbps         = 13 [json_name = "average_kbps"];
  google.protobuf.DoubleValue max_kbps             = 14 [json_name = "max_kbps"];
  google.protobuf.DoubleValue max_idr_delta_millis = 25 [json_name = "max_idr_delta"];
}

message ChannelPropertiesStreamViewcountsRequest {}

//
// Sample output from usher.justin.tv/channel_properties/show/lirik.json
//
// [
//   {
//     "max_idr_delta": 2000,
//     "average_kbps": 8446.64435518,
//     "height": 1080,
//     "channels": 2,
//     "audio_codec": "mp4a.40.2",
//     "id": 865432901,
//     "width": 1920,
//     "idr_aligned_percent": 1,
//     "twitch_content": true,
//     "avc_level": "42",
//     "customer_id": "twitch",
//     "channel": "lirik",
//     "max_kbps": 10723.7869822,
//     "target_fps": null,
//     "average_fps": 60.0303951368,
//     "video_codec": "avc1.64002A",
//     "avc_profile": "High",
//     "channel_id": 23161357,
//     "sample_rate": 48000,
//     "updated_on": 1529445583,
//     "content_id": "23161357",
//     "vfr": null
//   }
// ]


message ChannelPropertiesLiveHLSChannelsRequest {}
message ChannelPropertiesLiveHLSChannelsResponse {
  repeated string channels = 1 [json_name = "channels"];
}

message ChannelPropertiesListRequest {
  // 1 to 100, use for pagination
  int32 limit                = 1 [json_name = "limit"];

  // offset to start from, use for pagination
  int32 offset               = 2 [json_name = "offset"];

  // comma-separated list of channel names
  string channel             = 3 [json_name = "channel"];

  // comma-separated list of channel ids
  string channel_id          = 4 [json_name = "channel_id"];
}

message ListOf_ChannelPropertiesListResponse {
  // This is actually just an anonymous list in the response
  repeated ChannelPropertiesListItem channel_properties = 1;
}

message ChannelPropertiesListItem {
  string avc_level = 1 [json_name = "avc_level"];
  string avc_profile = 2 [json_name = "avc_profile"];
  float average_fps = 3 [json_name = "average_fps"];
  int64 broadcast_part = 4 [json_name = "broadcast_part"];
  string broadcaster = 5 [json_name = "broadcaster"];
  string channel = 6 [json_name = "channel"];
  int64 channel_count = 7 [json_name = "channel_count"];
  int64 channel_id = 8 [json_name = "channel_id"];
  string client_id = 9 [json_name = "client_id"];
  string configuration = 10 [json_name = "configuration"];
  int64 delay_length = 11 [json_name = "delay_length"];
  int64 embed_count = 12 [json_name = "embed_count"];
  bool encrypted = 13 [json_name = "encrypted"];
  string geo = 14 [json_name = "geo"];
  bool hls = 15 [json_name = "hls"];
  int64 id = 16 [json_name = "id"];
  int64 minimum_height = 17 [json_name = "minimum_height"];
  string minimum_level = 18 [json_name = "minimum_level"];
  string minimum_profile = 19 [json_name = "minimum_profile"];
  bool partner = 20 [json_name = "partner"];
  int64 site_count = 21 [json_name = "site_count"];

  // Timestamp in rfc3339
  string up_time                                 = 22 [json_name = "up_time"];
  // time object generated from original up_time string
  google.protobuf.Timestamp up_time_timestamp    = 23 [json_name = "up_time_timestamp"];

  // Timestamp in rfc3339
  string updated_on                              = 24 [json_name = "updated_on"];
  // time object generated from original updated_on string
  google.protobuf.Timestamp updated_on_timestamp = 25 [json_name = "updated_on_timestamp"];

  float video_bitrate = 26 [json_name = "video_bitrate"];
  string video_codec = 27 [json_name = "video_codec"];
  int64 video_height = 28 [json_name = "video_height"];
  int64 video_width = 29 [json_name = "video_width"];
  int64 vod_id = 30 [json_name = "vod_id"];
}

