/* eslint-disable */
import Long from "long";
import { grpc } from "@improbable-eng/grpc-web";
import _m0 from "protobufjs/minimal";
import { Duration } from "./google/protobuf/duration";
import { Observable } from "rxjs";
import { BrowserHeaders } from "browser-headers";
import { share } from "rxjs/operators";

export const protobufPackage = "media_set";

export enum AudioFormat {
  WAV = 0,
  MP3 = 1,
  UNRECOGNIZED = -1,
}

export function audioFormatFromJSON(object: any): AudioFormat {
  switch (object) {
    case 0:
    case "WAV":
      return AudioFormat.WAV;
    case 1:
    case "MP3":
      return AudioFormat.MP3;
    case -1:
    case "UNRECOGNIZED":
    default:
      return AudioFormat.UNRECOGNIZED;
  }
}

export function audioFormatToJSON(object: AudioFormat): string {
  switch (object) {
    case AudioFormat.WAV:
      return "WAV";
    case AudioFormat.MP3:
      return "MP3";
    default:
      return "UNKNOWN";
  }
}

export interface MediaSet {
  id: string;
  youtubeId: string;
  title: string;
  description: string;
  author: string;
  audioChannels: number;
  audioApproxFrames: number;
  audioFrames: number;
  audioSampleRate: number;
  audioYoutubeItag: number;
  audioMimeType: string;
  videoDuration?: Duration;
  videoYoutubeItag: number;
  videoMimeType: string;
}

export interface GetRequest {
  youtubeId: string;
}

export interface GetPeaksRequest {
  id: string;
  numBins: number;
}

export interface GetPeaksProgress {
  peaks: number[];
  percentComplete: number;
  url: string;
  audioFrames: number;
}

export interface GetPeaksForSegmentRequest {
  id: string;
  numBins: number;
  startFrame: number;
  endFrame: number;
}

export interface GetPeaksForSegmentResponse {
  peaks: number[];
}

export interface GetAudioSegmentRequest {
  id: string;
  startFrame: number;
  endFrame: number;
  format: AudioFormat;
}

export interface GetAudioSegmentProgress {
  percentComplete: number;
  audioData: Uint8Array;
}

export interface GetVideoRequest {
  id: string;
}

export interface GetVideoProgress {
  percentComplete: number;
  url: string;
}

export interface GetVideoThumbnailRequest {
  id: string;
}

export interface GetVideoThumbnailResponse {
  image: Uint8Array;
  width: number;
  height: number;
}

function createBaseMediaSet(): MediaSet {
  return {
    id: "",
    youtubeId: "",
    title: "",
    description: "",
    author: "",
    audioChannels: 0,
    audioApproxFrames: 0,
    audioFrames: 0,
    audioSampleRate: 0,
    audioYoutubeItag: 0,
    audioMimeType: "",
    videoDuration: undefined,
    videoYoutubeItag: 0,
    videoMimeType: "",
  };
}

export const MediaSet = {
  encode(
    message: MediaSet,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.id !== "") {
      writer.uint32(10).string(message.id);
    }
    if (message.youtubeId !== "") {
      writer.uint32(18).string(message.youtubeId);
    }
    if (message.title !== "") {
      writer.uint32(98).string(message.title);
    }
    if (message.description !== "") {
      writer.uint32(106).string(message.description);
    }
    if (message.author !== "") {
      writer.uint32(114).string(message.author);
    }
    if (message.audioChannels !== 0) {
      writer.uint32(24).int32(message.audioChannels);
    }
    if (message.audioApproxFrames !== 0) {
      writer.uint32(32).int64(message.audioApproxFrames);
    }
    if (message.audioFrames !== 0) {
      writer.uint32(40).int64(message.audioFrames);
    }
    if (message.audioSampleRate !== 0) {
      writer.uint32(48).int32(message.audioSampleRate);
    }
    if (message.audioYoutubeItag !== 0) {
      writer.uint32(56).int32(message.audioYoutubeItag);
    }
    if (message.audioMimeType !== "") {
      writer.uint32(66).string(message.audioMimeType);
    }
    if (message.videoDuration !== undefined) {
      Duration.encode(message.videoDuration, writer.uint32(74).fork()).ldelim();
    }
    if (message.videoYoutubeItag !== 0) {
      writer.uint32(80).int32(message.videoYoutubeItag);
    }
    if (message.videoMimeType !== "") {
      writer.uint32(90).string(message.videoMimeType);
    }
    return writer;
  },

  decode(input: _m0.Reader | Uint8Array, length?: number): MediaSet {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseMediaSet();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.id = reader.string();
          break;
        case 2:
          message.youtubeId = reader.string();
          break;
        case 12:
          message.title = reader.string();
          break;
        case 13:
          message.description = reader.string();
          break;
        case 14:
          message.author = reader.string();
          break;
        case 3:
          message.audioChannels = reader.int32();
          break;
        case 4:
          message.audioApproxFrames = longToNumber(reader.int64() as Long);
          break;
        case 5:
          message.audioFrames = longToNumber(reader.int64() as Long);
          break;
        case 6:
          message.audioSampleRate = reader.int32();
          break;
        case 7:
          message.audioYoutubeItag = reader.int32();
          break;
        case 8:
          message.audioMimeType = reader.string();
          break;
        case 9:
          message.videoDuration = Duration.decode(reader, reader.uint32());
          break;
        case 10:
          message.videoYoutubeItag = reader.int32();
          break;
        case 11:
          message.videoMimeType = reader.string();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): MediaSet {
    return {
      id: isSet(object.id) ? String(object.id) : "",
      youtubeId: isSet(object.youtubeId) ? String(object.youtubeId) : "",
      title: isSet(object.title) ? String(object.title) : "",
      description: isSet(object.description) ? String(object.description) : "",
      author: isSet(object.author) ? String(object.author) : "",
      audioChannels: isSet(object.audioChannels)
        ? Number(object.audioChannels)
        : 0,
      audioApproxFrames: isSet(object.audioApproxFrames)
        ? Number(object.audioApproxFrames)
        : 0,
      audioFrames: isSet(object.audioFrames) ? Number(object.audioFrames) : 0,
      audioSampleRate: isSet(object.audioSampleRate)
        ? Number(object.audioSampleRate)
        : 0,
      audioYoutubeItag: isSet(object.audioYoutubeItag)
        ? Number(object.audioYoutubeItag)
        : 0,
      audioMimeType: isSet(object.audioMimeType)
        ? String(object.audioMimeType)
        : "",
      videoDuration: isSet(object.videoDuration)
        ? Duration.fromJSON(object.videoDuration)
        : undefined,
      videoYoutubeItag: isSet(object.videoYoutubeItag)
        ? Number(object.videoYoutubeItag)
        : 0,
      videoMimeType: isSet(object.videoMimeType)
        ? String(object.videoMimeType)
        : "",
    };
  },

  toJSON(message: MediaSet): unknown {
    const obj: any = {};
    message.id !== undefined && (obj.id = message.id);
    message.youtubeId !== undefined && (obj.youtubeId = message.youtubeId);
    message.title !== undefined && (obj.title = message.title);
    message.description !== undefined &&
      (obj.description = message.description);
    message.author !== undefined && (obj.author = message.author);
    message.audioChannels !== undefined &&
      (obj.audioChannels = Math.round(message.audioChannels));
    message.audioApproxFrames !== undefined &&
      (obj.audioApproxFrames = Math.round(message.audioApproxFrames));
    message.audioFrames !== undefined &&
      (obj.audioFrames = Math.round(message.audioFrames));
    message.audioSampleRate !== undefined &&
      (obj.audioSampleRate = Math.round(message.audioSampleRate));
    message.audioYoutubeItag !== undefined &&
      (obj.audioYoutubeItag = Math.round(message.audioYoutubeItag));
    message.audioMimeType !== undefined &&
      (obj.audioMimeType = message.audioMimeType);
    message.videoDuration !== undefined &&
      (obj.videoDuration = message.videoDuration
        ? Duration.toJSON(message.videoDuration)
        : undefined);
    message.videoYoutubeItag !== undefined &&
      (obj.videoYoutubeItag = Math.round(message.videoYoutubeItag));
    message.videoMimeType !== undefined &&
      (obj.videoMimeType = message.videoMimeType);
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<MediaSet>, I>>(object: I): MediaSet {
    const message = createBaseMediaSet();
    message.id = object.id ?? "";
    message.youtubeId = object.youtubeId ?? "";
    message.title = object.title ?? "";
    message.description = object.description ?? "";
    message.author = object.author ?? "";
    message.audioChannels = object.audioChannels ?? 0;
    message.audioApproxFrames = object.audioApproxFrames ?? 0;
    message.audioFrames = object.audioFrames ?? 0;
    message.audioSampleRate = object.audioSampleRate ?? 0;
    message.audioYoutubeItag = object.audioYoutubeItag ?? 0;
    message.audioMimeType = object.audioMimeType ?? "";
    message.videoDuration =
      object.videoDuration !== undefined && object.videoDuration !== null
        ? Duration.fromPartial(object.videoDuration)
        : undefined;
    message.videoYoutubeItag = object.videoYoutubeItag ?? 0;
    message.videoMimeType = object.videoMimeType ?? "";
    return message;
  },
};

function createBaseGetRequest(): GetRequest {
  return { youtubeId: "" };
}

export const GetRequest = {
  encode(
    message: GetRequest,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.youtubeId !== "") {
      writer.uint32(10).string(message.youtubeId);
    }
    return writer;
  },

  decode(input: _m0.Reader | Uint8Array, length?: number): GetRequest {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetRequest();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.youtubeId = reader.string();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetRequest {
    return {
      youtubeId: isSet(object.youtubeId) ? String(object.youtubeId) : "",
    };
  },

  toJSON(message: GetRequest): unknown {
    const obj: any = {};
    message.youtubeId !== undefined && (obj.youtubeId = message.youtubeId);
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetRequest>, I>>(
    object: I
  ): GetRequest {
    const message = createBaseGetRequest();
    message.youtubeId = object.youtubeId ?? "";
    return message;
  },
};

function createBaseGetPeaksRequest(): GetPeaksRequest {
  return { id: "", numBins: 0 };
}

export const GetPeaksRequest = {
  encode(
    message: GetPeaksRequest,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.id !== "") {
      writer.uint32(10).string(message.id);
    }
    if (message.numBins !== 0) {
      writer.uint32(16).int32(message.numBins);
    }
    return writer;
  },

  decode(input: _m0.Reader | Uint8Array, length?: number): GetPeaksRequest {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetPeaksRequest();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.id = reader.string();
          break;
        case 2:
          message.numBins = reader.int32();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetPeaksRequest {
    return {
      id: isSet(object.id) ? String(object.id) : "",
      numBins: isSet(object.numBins) ? Number(object.numBins) : 0,
    };
  },

  toJSON(message: GetPeaksRequest): unknown {
    const obj: any = {};
    message.id !== undefined && (obj.id = message.id);
    message.numBins !== undefined &&
      (obj.numBins = Math.round(message.numBins));
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetPeaksRequest>, I>>(
    object: I
  ): GetPeaksRequest {
    const message = createBaseGetPeaksRequest();
    message.id = object.id ?? "";
    message.numBins = object.numBins ?? 0;
    return message;
  },
};

function createBaseGetPeaksProgress(): GetPeaksProgress {
  return { peaks: [], percentComplete: 0, url: "", audioFrames: 0 };
}

export const GetPeaksProgress = {
  encode(
    message: GetPeaksProgress,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    writer.uint32(10).fork();
    for (const v of message.peaks) {
      writer.int32(v);
    }
    writer.ldelim();
    if (message.percentComplete !== 0) {
      writer.uint32(21).float(message.percentComplete);
    }
    if (message.url !== "") {
      writer.uint32(26).string(message.url);
    }
    if (message.audioFrames !== 0) {
      writer.uint32(32).int64(message.audioFrames);
    }
    return writer;
  },

  decode(input: _m0.Reader | Uint8Array, length?: number): GetPeaksProgress {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetPeaksProgress();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          if ((tag & 7) === 2) {
            const end2 = reader.uint32() + reader.pos;
            while (reader.pos < end2) {
              message.peaks.push(reader.int32());
            }
          } else {
            message.peaks.push(reader.int32());
          }
          break;
        case 2:
          message.percentComplete = reader.float();
          break;
        case 3:
          message.url = reader.string();
          break;
        case 4:
          message.audioFrames = longToNumber(reader.int64() as Long);
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetPeaksProgress {
    return {
      peaks: Array.isArray(object?.peaks)
        ? object.peaks.map((e: any) => Number(e))
        : [],
      percentComplete: isSet(object.percentComplete)
        ? Number(object.percentComplete)
        : 0,
      url: isSet(object.url) ? String(object.url) : "",
      audioFrames: isSet(object.audioFrames) ? Number(object.audioFrames) : 0,
    };
  },

  toJSON(message: GetPeaksProgress): unknown {
    const obj: any = {};
    if (message.peaks) {
      obj.peaks = message.peaks.map((e) => Math.round(e));
    } else {
      obj.peaks = [];
    }
    message.percentComplete !== undefined &&
      (obj.percentComplete = message.percentComplete);
    message.url !== undefined && (obj.url = message.url);
    message.audioFrames !== undefined &&
      (obj.audioFrames = Math.round(message.audioFrames));
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetPeaksProgress>, I>>(
    object: I
  ): GetPeaksProgress {
    const message = createBaseGetPeaksProgress();
    message.peaks = object.peaks?.map((e) => e) || [];
    message.percentComplete = object.percentComplete ?? 0;
    message.url = object.url ?? "";
    message.audioFrames = object.audioFrames ?? 0;
    return message;
  },
};

function createBaseGetPeaksForSegmentRequest(): GetPeaksForSegmentRequest {
  return { id: "", numBins: 0, startFrame: 0, endFrame: 0 };
}

export const GetPeaksForSegmentRequest = {
  encode(
    message: GetPeaksForSegmentRequest,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.id !== "") {
      writer.uint32(10).string(message.id);
    }
    if (message.numBins !== 0) {
      writer.uint32(16).int32(message.numBins);
    }
    if (message.startFrame !== 0) {
      writer.uint32(24).int64(message.startFrame);
    }
    if (message.endFrame !== 0) {
      writer.uint32(32).int64(message.endFrame);
    }
    return writer;
  },

  decode(
    input: _m0.Reader | Uint8Array,
    length?: number
  ): GetPeaksForSegmentRequest {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetPeaksForSegmentRequest();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.id = reader.string();
          break;
        case 2:
          message.numBins = reader.int32();
          break;
        case 3:
          message.startFrame = longToNumber(reader.int64() as Long);
          break;
        case 4:
          message.endFrame = longToNumber(reader.int64() as Long);
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetPeaksForSegmentRequest {
    return {
      id: isSet(object.id) ? String(object.id) : "",
      numBins: isSet(object.numBins) ? Number(object.numBins) : 0,
      startFrame: isSet(object.startFrame) ? Number(object.startFrame) : 0,
      endFrame: isSet(object.endFrame) ? Number(object.endFrame) : 0,
    };
  },

  toJSON(message: GetPeaksForSegmentRequest): unknown {
    const obj: any = {};
    message.id !== undefined && (obj.id = message.id);
    message.numBins !== undefined &&
      (obj.numBins = Math.round(message.numBins));
    message.startFrame !== undefined &&
      (obj.startFrame = Math.round(message.startFrame));
    message.endFrame !== undefined &&
      (obj.endFrame = Math.round(message.endFrame));
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetPeaksForSegmentRequest>, I>>(
    object: I
  ): GetPeaksForSegmentRequest {
    const message = createBaseGetPeaksForSegmentRequest();
    message.id = object.id ?? "";
    message.numBins = object.numBins ?? 0;
    message.startFrame = object.startFrame ?? 0;
    message.endFrame = object.endFrame ?? 0;
    return message;
  },
};

function createBaseGetPeaksForSegmentResponse(): GetPeaksForSegmentResponse {
  return { peaks: [] };
}

export const GetPeaksForSegmentResponse = {
  encode(
    message: GetPeaksForSegmentResponse,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    writer.uint32(10).fork();
    for (const v of message.peaks) {
      writer.int32(v);
    }
    writer.ldelim();
    return writer;
  },

  decode(
    input: _m0.Reader | Uint8Array,
    length?: number
  ): GetPeaksForSegmentResponse {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetPeaksForSegmentResponse();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          if ((tag & 7) === 2) {
            const end2 = reader.uint32() + reader.pos;
            while (reader.pos < end2) {
              message.peaks.push(reader.int32());
            }
          } else {
            message.peaks.push(reader.int32());
          }
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetPeaksForSegmentResponse {
    return {
      peaks: Array.isArray(object?.peaks)
        ? object.peaks.map((e: any) => Number(e))
        : [],
    };
  },

  toJSON(message: GetPeaksForSegmentResponse): unknown {
    const obj: any = {};
    if (message.peaks) {
      obj.peaks = message.peaks.map((e) => Math.round(e));
    } else {
      obj.peaks = [];
    }
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetPeaksForSegmentResponse>, I>>(
    object: I
  ): GetPeaksForSegmentResponse {
    const message = createBaseGetPeaksForSegmentResponse();
    message.peaks = object.peaks?.map((e) => e) || [];
    return message;
  },
};

function createBaseGetAudioSegmentRequest(): GetAudioSegmentRequest {
  return { id: "", startFrame: 0, endFrame: 0, format: 0 };
}

export const GetAudioSegmentRequest = {
  encode(
    message: GetAudioSegmentRequest,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.id !== "") {
      writer.uint32(10).string(message.id);
    }
    if (message.startFrame !== 0) {
      writer.uint32(16).int64(message.startFrame);
    }
    if (message.endFrame !== 0) {
      writer.uint32(24).int64(message.endFrame);
    }
    if (message.format !== 0) {
      writer.uint32(32).int32(message.format);
    }
    return writer;
  },

  decode(
    input: _m0.Reader | Uint8Array,
    length?: number
  ): GetAudioSegmentRequest {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetAudioSegmentRequest();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.id = reader.string();
          break;
        case 2:
          message.startFrame = longToNumber(reader.int64() as Long);
          break;
        case 3:
          message.endFrame = longToNumber(reader.int64() as Long);
          break;
        case 4:
          message.format = reader.int32() as any;
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetAudioSegmentRequest {
    return {
      id: isSet(object.id) ? String(object.id) : "",
      startFrame: isSet(object.startFrame) ? Number(object.startFrame) : 0,
      endFrame: isSet(object.endFrame) ? Number(object.endFrame) : 0,
      format: isSet(object.format) ? audioFormatFromJSON(object.format) : 0,
    };
  },

  toJSON(message: GetAudioSegmentRequest): unknown {
    const obj: any = {};
    message.id !== undefined && (obj.id = message.id);
    message.startFrame !== undefined &&
      (obj.startFrame = Math.round(message.startFrame));
    message.endFrame !== undefined &&
      (obj.endFrame = Math.round(message.endFrame));
    message.format !== undefined &&
      (obj.format = audioFormatToJSON(message.format));
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetAudioSegmentRequest>, I>>(
    object: I
  ): GetAudioSegmentRequest {
    const message = createBaseGetAudioSegmentRequest();
    message.id = object.id ?? "";
    message.startFrame = object.startFrame ?? 0;
    message.endFrame = object.endFrame ?? 0;
    message.format = object.format ?? 0;
    return message;
  },
};

function createBaseGetAudioSegmentProgress(): GetAudioSegmentProgress {
  return { percentComplete: 0, audioData: new Uint8Array() };
}

export const GetAudioSegmentProgress = {
  encode(
    message: GetAudioSegmentProgress,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.percentComplete !== 0) {
      writer.uint32(29).float(message.percentComplete);
    }
    if (message.audioData.length !== 0) {
      writer.uint32(34).bytes(message.audioData);
    }
    return writer;
  },

  decode(
    input: _m0.Reader | Uint8Array,
    length?: number
  ): GetAudioSegmentProgress {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetAudioSegmentProgress();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 3:
          message.percentComplete = reader.float();
          break;
        case 4:
          message.audioData = reader.bytes();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetAudioSegmentProgress {
    return {
      percentComplete: isSet(object.percentComplete)
        ? Number(object.percentComplete)
        : 0,
      audioData: isSet(object.audioData)
        ? bytesFromBase64(object.audioData)
        : new Uint8Array(),
    };
  },

  toJSON(message: GetAudioSegmentProgress): unknown {
    const obj: any = {};
    message.percentComplete !== undefined &&
      (obj.percentComplete = message.percentComplete);
    message.audioData !== undefined &&
      (obj.audioData = base64FromBytes(
        message.audioData !== undefined ? message.audioData : new Uint8Array()
      ));
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetAudioSegmentProgress>, I>>(
    object: I
  ): GetAudioSegmentProgress {
    const message = createBaseGetAudioSegmentProgress();
    message.percentComplete = object.percentComplete ?? 0;
    message.audioData = object.audioData ?? new Uint8Array();
    return message;
  },
};

function createBaseGetVideoRequest(): GetVideoRequest {
  return { id: "" };
}

export const GetVideoRequest = {
  encode(
    message: GetVideoRequest,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.id !== "") {
      writer.uint32(10).string(message.id);
    }
    return writer;
  },

  decode(input: _m0.Reader | Uint8Array, length?: number): GetVideoRequest {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetVideoRequest();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.id = reader.string();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetVideoRequest {
    return {
      id: isSet(object.id) ? String(object.id) : "",
    };
  },

  toJSON(message: GetVideoRequest): unknown {
    const obj: any = {};
    message.id !== undefined && (obj.id = message.id);
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetVideoRequest>, I>>(
    object: I
  ): GetVideoRequest {
    const message = createBaseGetVideoRequest();
    message.id = object.id ?? "";
    return message;
  },
};

function createBaseGetVideoProgress(): GetVideoProgress {
  return { percentComplete: 0, url: "" };
}

export const GetVideoProgress = {
  encode(
    message: GetVideoProgress,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.percentComplete !== 0) {
      writer.uint32(13).float(message.percentComplete);
    }
    if (message.url !== "") {
      writer.uint32(18).string(message.url);
    }
    return writer;
  },

  decode(input: _m0.Reader | Uint8Array, length?: number): GetVideoProgress {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetVideoProgress();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.percentComplete = reader.float();
          break;
        case 2:
          message.url = reader.string();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetVideoProgress {
    return {
      percentComplete: isSet(object.percentComplete)
        ? Number(object.percentComplete)
        : 0,
      url: isSet(object.url) ? String(object.url) : "",
    };
  },

  toJSON(message: GetVideoProgress): unknown {
    const obj: any = {};
    message.percentComplete !== undefined &&
      (obj.percentComplete = message.percentComplete);
    message.url !== undefined && (obj.url = message.url);
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetVideoProgress>, I>>(
    object: I
  ): GetVideoProgress {
    const message = createBaseGetVideoProgress();
    message.percentComplete = object.percentComplete ?? 0;
    message.url = object.url ?? "";
    return message;
  },
};

function createBaseGetVideoThumbnailRequest(): GetVideoThumbnailRequest {
  return { id: "" };
}

export const GetVideoThumbnailRequest = {
  encode(
    message: GetVideoThumbnailRequest,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.id !== "") {
      writer.uint32(10).string(message.id);
    }
    return writer;
  },

  decode(
    input: _m0.Reader | Uint8Array,
    length?: number
  ): GetVideoThumbnailRequest {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetVideoThumbnailRequest();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.id = reader.string();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetVideoThumbnailRequest {
    return {
      id: isSet(object.id) ? String(object.id) : "",
    };
  },

  toJSON(message: GetVideoThumbnailRequest): unknown {
    const obj: any = {};
    message.id !== undefined && (obj.id = message.id);
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetVideoThumbnailRequest>, I>>(
    object: I
  ): GetVideoThumbnailRequest {
    const message = createBaseGetVideoThumbnailRequest();
    message.id = object.id ?? "";
    return message;
  },
};

function createBaseGetVideoThumbnailResponse(): GetVideoThumbnailResponse {
  return { image: new Uint8Array(), width: 0, height: 0 };
}

export const GetVideoThumbnailResponse = {
  encode(
    message: GetVideoThumbnailResponse,
    writer: _m0.Writer = _m0.Writer.create()
  ): _m0.Writer {
    if (message.image.length !== 0) {
      writer.uint32(10).bytes(message.image);
    }
    if (message.width !== 0) {
      writer.uint32(16).int32(message.width);
    }
    if (message.height !== 0) {
      writer.uint32(24).int32(message.height);
    }
    return writer;
  },

  decode(
    input: _m0.Reader | Uint8Array,
    length?: number
  ): GetVideoThumbnailResponse {
    const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseGetVideoThumbnailResponse();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          message.image = reader.bytes();
          break;
        case 2:
          message.width = reader.int32();
          break;
        case 3:
          message.height = reader.int32();
          break;
        default:
          reader.skipType(tag & 7);
          break;
      }
    }
    return message;
  },

  fromJSON(object: any): GetVideoThumbnailResponse {
    return {
      image: isSet(object.image)
        ? bytesFromBase64(object.image)
        : new Uint8Array(),
      width: isSet(object.width) ? Number(object.width) : 0,
      height: isSet(object.height) ? Number(object.height) : 0,
    };
  },

  toJSON(message: GetVideoThumbnailResponse): unknown {
    const obj: any = {};
    message.image !== undefined &&
      (obj.image = base64FromBytes(
        message.image !== undefined ? message.image : new Uint8Array()
      ));
    message.width !== undefined && (obj.width = Math.round(message.width));
    message.height !== undefined && (obj.height = Math.round(message.height));
    return obj;
  },

  fromPartial<I extends Exact<DeepPartial<GetVideoThumbnailResponse>, I>>(
    object: I
  ): GetVideoThumbnailResponse {
    const message = createBaseGetVideoThumbnailResponse();
    message.image = object.image ?? new Uint8Array();
    message.width = object.width ?? 0;
    message.height = object.height ?? 0;
    return message;
  },
};

export interface MediaSetService {
  Get(
    request: DeepPartial<GetRequest>,
    metadata?: grpc.Metadata
  ): Promise<MediaSet>;
  GetPeaks(
    request: DeepPartial<GetPeaksRequest>,
    metadata?: grpc.Metadata
  ): Observable<GetPeaksProgress>;
  GetPeaksForSegment(
    request: DeepPartial<GetPeaksForSegmentRequest>,
    metadata?: grpc.Metadata
  ): Promise<GetPeaksForSegmentResponse>;
  GetAudioSegment(
    request: DeepPartial<GetAudioSegmentRequest>,
    metadata?: grpc.Metadata
  ): Observable<GetAudioSegmentProgress>;
  GetVideo(
    request: DeepPartial<GetVideoRequest>,
    metadata?: grpc.Metadata
  ): Observable<GetVideoProgress>;
  GetVideoThumbnail(
    request: DeepPartial<GetVideoThumbnailRequest>,
    metadata?: grpc.Metadata
  ): Promise<GetVideoThumbnailResponse>;
}

export class MediaSetServiceClientImpl implements MediaSetService {
  private readonly rpc: Rpc;

  constructor(rpc: Rpc) {
    this.rpc = rpc;
    this.Get = this.Get.bind(this);
    this.GetPeaks = this.GetPeaks.bind(this);
    this.GetPeaksForSegment = this.GetPeaksForSegment.bind(this);
    this.GetAudioSegment = this.GetAudioSegment.bind(this);
    this.GetVideo = this.GetVideo.bind(this);
    this.GetVideoThumbnail = this.GetVideoThumbnail.bind(this);
  }

  Get(
    request: DeepPartial<GetRequest>,
    metadata?: grpc.Metadata
  ): Promise<MediaSet> {
    return this.rpc.unary(
      MediaSetServiceGetDesc,
      GetRequest.fromPartial(request),
      metadata
    );
  }

  GetPeaks(
    request: DeepPartial<GetPeaksRequest>,
    metadata?: grpc.Metadata
  ): Observable<GetPeaksProgress> {
    return this.rpc.invoke(
      MediaSetServiceGetPeaksDesc,
      GetPeaksRequest.fromPartial(request),
      metadata
    );
  }

  GetPeaksForSegment(
    request: DeepPartial<GetPeaksForSegmentRequest>,
    metadata?: grpc.Metadata
  ): Promise<GetPeaksForSegmentResponse> {
    return this.rpc.unary(
      MediaSetServiceGetPeaksForSegmentDesc,
      GetPeaksForSegmentRequest.fromPartial(request),
      metadata
    );
  }

  GetAudioSegment(
    request: DeepPartial<GetAudioSegmentRequest>,
    metadata?: grpc.Metadata
  ): Observable<GetAudioSegmentProgress> {
    return this.rpc.invoke(
      MediaSetServiceGetAudioSegmentDesc,
      GetAudioSegmentRequest.fromPartial(request),
      metadata
    );
  }

  GetVideo(
    request: DeepPartial<GetVideoRequest>,
    metadata?: grpc.Metadata
  ): Observable<GetVideoProgress> {
    return this.rpc.invoke(
      MediaSetServiceGetVideoDesc,
      GetVideoRequest.fromPartial(request),
      metadata
    );
  }

  GetVideoThumbnail(
    request: DeepPartial<GetVideoThumbnailRequest>,
    metadata?: grpc.Metadata
  ): Promise<GetVideoThumbnailResponse> {
    return this.rpc.unary(
      MediaSetServiceGetVideoThumbnailDesc,
      GetVideoThumbnailRequest.fromPartial(request),
      metadata
    );
  }
}

export const MediaSetServiceDesc = {
  serviceName: "media_set.MediaSetService",
};

export const MediaSetServiceGetDesc: UnaryMethodDefinitionish = {
  methodName: "Get",
  service: MediaSetServiceDesc,
  requestStream: false,
  responseStream: false,
  requestType: {
    serializeBinary() {
      return GetRequest.encode(this).finish();
    },
  } as any,
  responseType: {
    deserializeBinary(data: Uint8Array) {
      return {
        ...MediaSet.decode(data),
        toObject() {
          return this;
        },
      };
    },
  } as any,
};

export const MediaSetServiceGetPeaksDesc: UnaryMethodDefinitionish = {
  methodName: "GetPeaks",
  service: MediaSetServiceDesc,
  requestStream: false,
  responseStream: true,
  requestType: {
    serializeBinary() {
      return GetPeaksRequest.encode(this).finish();
    },
  } as any,
  responseType: {
    deserializeBinary(data: Uint8Array) {
      return {
        ...GetPeaksProgress.decode(data),
        toObject() {
          return this;
        },
      };
    },
  } as any,
};

export const MediaSetServiceGetPeaksForSegmentDesc: UnaryMethodDefinitionish = {
  methodName: "GetPeaksForSegment",
  service: MediaSetServiceDesc,
  requestStream: false,
  responseStream: false,
  requestType: {
    serializeBinary() {
      return GetPeaksForSegmentRequest.encode(this).finish();
    },
  } as any,
  responseType: {
    deserializeBinary(data: Uint8Array) {
      return {
        ...GetPeaksForSegmentResponse.decode(data),
        toObject() {
          return this;
        },
      };
    },
  } as any,
};

export const MediaSetServiceGetAudioSegmentDesc: UnaryMethodDefinitionish = {
  methodName: "GetAudioSegment",
  service: MediaSetServiceDesc,
  requestStream: false,
  responseStream: true,
  requestType: {
    serializeBinary() {
      return GetAudioSegmentRequest.encode(this).finish();
    },
  } as any,
  responseType: {
    deserializeBinary(data: Uint8Array) {
      return {
        ...GetAudioSegmentProgress.decode(data),
        toObject() {
          return this;
        },
      };
    },
  } as any,
};

export const MediaSetServiceGetVideoDesc: UnaryMethodDefinitionish = {
  methodName: "GetVideo",
  service: MediaSetServiceDesc,
  requestStream: false,
  responseStream: true,
  requestType: {
    serializeBinary() {
      return GetVideoRequest.encode(this).finish();
    },
  } as any,
  responseType: {
    deserializeBinary(data: Uint8Array) {
      return {
        ...GetVideoProgress.decode(data),
        toObject() {
          return this;
        },
      };
    },
  } as any,
};

export const MediaSetServiceGetVideoThumbnailDesc: UnaryMethodDefinitionish = {
  methodName: "GetVideoThumbnail",
  service: MediaSetServiceDesc,
  requestStream: false,
  responseStream: false,
  requestType: {
    serializeBinary() {
      return GetVideoThumbnailRequest.encode(this).finish();
    },
  } as any,
  responseType: {
    deserializeBinary(data: Uint8Array) {
      return {
        ...GetVideoThumbnailResponse.decode(data),
        toObject() {
          return this;
        },
      };
    },
  } as any,
};

interface UnaryMethodDefinitionishR
  extends grpc.UnaryMethodDefinition<any, any> {
  requestStream: any;
  responseStream: any;
}

type UnaryMethodDefinitionish = UnaryMethodDefinitionishR;

interface Rpc {
  unary<T extends UnaryMethodDefinitionish>(
    methodDesc: T,
    request: any,
    metadata: grpc.Metadata | undefined
  ): Promise<any>;
  invoke<T extends UnaryMethodDefinitionish>(
    methodDesc: T,
    request: any,
    metadata: grpc.Metadata | undefined
  ): Observable<any>;
}

export class GrpcWebImpl {
  private host: string;
  private options: {
    transport?: grpc.TransportFactory;
    streamingTransport?: grpc.TransportFactory;
    debug?: boolean;
    metadata?: grpc.Metadata;
  };

  constructor(
    host: string,
    options: {
      transport?: grpc.TransportFactory;
      streamingTransport?: grpc.TransportFactory;
      debug?: boolean;
      metadata?: grpc.Metadata;
    }
  ) {
    this.host = host;
    this.options = options;
  }

  unary<T extends UnaryMethodDefinitionish>(
    methodDesc: T,
    _request: any,
    metadata: grpc.Metadata | undefined
  ): Promise<any> {
    const request = { ..._request, ...methodDesc.requestType };
    const maybeCombinedMetadata =
      metadata && this.options.metadata
        ? new BrowserHeaders({
            ...this.options?.metadata.headersMap,
            ...metadata?.headersMap,
          })
        : metadata || this.options.metadata;
    return new Promise((resolve, reject) => {
      grpc.unary(methodDesc, {
        request,
        host: this.host,
        metadata: maybeCombinedMetadata,
        transport: this.options.transport,
        debug: this.options.debug,
        onEnd: function (response) {
          if (response.status === grpc.Code.OK) {
            resolve(response.message);
          } else {
            const err = new Error(response.statusMessage) as any;
            err.code = response.status;
            err.metadata = response.trailers;
            reject(err);
          }
        },
      });
    });
  }

  invoke<T extends UnaryMethodDefinitionish>(
    methodDesc: T,
    _request: any,
    metadata: grpc.Metadata | undefined
  ): Observable<any> {
    // Status Response Codes (https://developers.google.com/maps-booking/reference/grpc-api/status_codes)
    const upStreamCodes = [2, 4, 8, 9, 10, 13, 14, 15];
    const DEFAULT_TIMEOUT_TIME: number = 3_000;
    const request = { ..._request, ...methodDesc.requestType };
    const maybeCombinedMetadata =
      metadata && this.options.metadata
        ? new BrowserHeaders({
            ...this.options?.metadata.headersMap,
            ...metadata?.headersMap,
          })
        : metadata || this.options.metadata;
    return new Observable((observer) => {
      const upStream = () => {
        const client = grpc.invoke(methodDesc, {
          host: this.host,
          request,
          transport: this.options.streamingTransport || this.options.transport,
          metadata: maybeCombinedMetadata,
          debug: this.options.debug,
          onMessage: (next) => observer.next(next),
          onEnd: (code: grpc.Code, message: string) => {
            if (code === 0) {
              observer.complete();
            } else if (upStreamCodes.includes(code)) {
              setTimeout(upStream, DEFAULT_TIMEOUT_TIME);
            } else {
              observer.error(new Error(`Error ${code} ${message}`));
            }
          },
        });
        observer.add(() => client.close());
      };
      upStream();
    }).pipe(share());
  }
}

declare var self: any | undefined;
declare var window: any | undefined;
declare var global: any | undefined;
var globalThis: any = (() => {
  if (typeof globalThis !== "undefined") return globalThis;
  if (typeof self !== "undefined") return self;
  if (typeof window !== "undefined") return window;
  if (typeof global !== "undefined") return global;
  throw "Unable to locate global object";
})();

const atob: (b64: string) => string =
  globalThis.atob ||
  ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary"));
function bytesFromBase64(b64: string): Uint8Array {
  const bin = atob(b64);
  const arr = new Uint8Array(bin.length);
  for (let i = 0; i < bin.length; ++i) {
    arr[i] = bin.charCodeAt(i);
  }
  return arr;
}

const btoa: (bin: string) => string =
  globalThis.btoa ||
  ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64"));
function base64FromBytes(arr: Uint8Array): string {
  const bin: string[] = [];
  for (const byte of arr) {
    bin.push(String.fromCharCode(byte));
  }
  return btoa(bin.join(""));
}

type Builtin =
  | Date
  | Function
  | Uint8Array
  | string
  | number
  | boolean
  | undefined;

export type DeepPartial<T> = T extends Builtin
  ? T
  : T extends Array<infer U>
  ? Array<DeepPartial<U>>
  : T extends ReadonlyArray<infer U>
  ? ReadonlyArray<DeepPartial<U>>
  : T extends {}
  ? { [K in keyof T]?: DeepPartial<T[K]> }
  : Partial<T>;

type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin
  ? P
  : P & { [K in keyof P]: Exact<P[K], I[K]> } & Record<
        Exclude<keyof I, KeysOfUnion<P>>,
        never
      >;

function longToNumber(long: Long): number {
  if (long.gt(Number.MAX_SAFE_INTEGER)) {
    throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
  }
  return long.toNumber();
}

if (_m0.util.Long !== Long) {
  _m0.util.Long = Long as any;
  _m0.configure();
}

function isSet(value: any): boolean {
  return value !== null && value !== undefined;
}
