Java Code Examples for com.google.android.exoplayer2.util.Util#getUtf8Bytes()

The following examples show how to use com.google.android.exoplayer2.util.Util#getUtf8Bytes() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MatroskaExtractor.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Formats {@code timeUs} using {@code timecodeFormat}, and sets it as the end timecode in {@code
 * subtitleSampleData}.
 */
private static byte[] formatSubtitleTimecode(
    long timeUs, String timecodeFormat, long lastTimecodeValueScalingFactor) {
  Assertions.checkArgument(timeUs != C.TIME_UNSET);
  byte[] timeCodeData;
  int hours = (int) (timeUs / (3600 * C.MICROS_PER_SECOND));
  timeUs -= (hours * 3600 * C.MICROS_PER_SECOND);
  int minutes = (int) (timeUs / (60 * C.MICROS_PER_SECOND));
  timeUs -= (minutes * 60 * C.MICROS_PER_SECOND);
  int seconds = (int) (timeUs / C.MICROS_PER_SECOND);
  timeUs -= (seconds * C.MICROS_PER_SECOND);
  int lastValue = (int) (timeUs / lastTimecodeValueScalingFactor);
  timeCodeData =
      Util.getUtf8Bytes(
          String.format(Locale.US, timecodeFormat, hours, minutes, seconds, lastValue));
  return timeCodeData;
}
 
Example 2
Source File: MatroskaExtractor.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
private static void setSampleDuration(byte[] subripSampleData, long durationUs,
    String timecodeFormat, int endTimecodeOffset, long lastTimecodeValueScalingFactor,
    byte[] emptyTimecode) {
  byte[] timeCodeData;
  if (durationUs == C.TIME_UNSET) {
    timeCodeData = emptyTimecode;
  } else {
    int hours = (int) (durationUs / (3600 * C.MICROS_PER_SECOND));
    durationUs -= (hours * 3600 * C.MICROS_PER_SECOND);
    int minutes = (int) (durationUs / (60 * C.MICROS_PER_SECOND));
    durationUs -= (minutes * 60 * C.MICROS_PER_SECOND);
    int seconds = (int) (durationUs / C.MICROS_PER_SECOND);
    durationUs -= (seconds * C.MICROS_PER_SECOND);
    int lastValue = (int) (durationUs / lastTimecodeValueScalingFactor);
    timeCodeData = Util.getUtf8Bytes(String.format(Locale.US, timecodeFormat, hours, minutes,
        seconds, lastValue));
  }
  System.arraycopy(timeCodeData, 0, subripSampleData, endTimecodeOffset, emptyTimecode.length);
}
 
Example 3
Source File: MatroskaExtractor.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
private static void setSampleDuration(byte[] subripSampleData, long durationUs,
    String timecodeFormat, int endTimecodeOffset, long lastTimecodeValueScalingFactor,
    byte[] emptyTimecode) {
  byte[] timeCodeData;
  if (durationUs == C.TIME_UNSET) {
    timeCodeData = emptyTimecode;
  } else {
    int hours = (int) (durationUs / (3600 * C.MICROS_PER_SECOND));
    durationUs -= (hours * 3600 * C.MICROS_PER_SECOND);
    int minutes = (int) (durationUs / (60 * C.MICROS_PER_SECOND));
    durationUs -= (minutes * 60 * C.MICROS_PER_SECOND);
    int seconds = (int) (durationUs / C.MICROS_PER_SECOND);
    durationUs -= (seconds * C.MICROS_PER_SECOND);
    int lastValue = (int) (durationUs / lastTimecodeValueScalingFactor);
    timeCodeData = Util.getUtf8Bytes(String.format(Locale.US, timecodeFormat, hours, minutes,
        seconds, lastValue));
  }
  System.arraycopy(timeCodeData, 0, subripSampleData, endTimecodeOffset, emptyTimecode.length);
}
 
Example 4
Source File: MatroskaExtractor.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
private static void setSampleDuration(byte[] subripSampleData, long durationUs,
    String timecodeFormat, int endTimecodeOffset, long lastTimecodeValueScalingFactor,
    byte[] emptyTimecode) {
  byte[] timeCodeData;
  if (durationUs == C.TIME_UNSET) {
    timeCodeData = emptyTimecode;
  } else {
    int hours = (int) (durationUs / (3600 * C.MICROS_PER_SECOND));
    durationUs -= (hours * 3600 * C.MICROS_PER_SECOND);
    int minutes = (int) (durationUs / (60 * C.MICROS_PER_SECOND));
    durationUs -= (minutes * 60 * C.MICROS_PER_SECOND);
    int seconds = (int) (durationUs / C.MICROS_PER_SECOND);
    durationUs -= (seconds * C.MICROS_PER_SECOND);
    int lastValue = (int) (durationUs / lastTimecodeValueScalingFactor);
    timeCodeData = Util.getUtf8Bytes(String.format(Locale.US, timecodeFormat, hours, minutes,
        seconds, lastValue));
  }
  System.arraycopy(timeCodeData, 0, subripSampleData, endTimecodeOffset, emptyTimecode.length);
}
 
Example 5
Source File: MatroskaExtractor.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
private static void setSampleDuration(byte[] subripSampleData, long durationUs,
    String timecodeFormat, int endTimecodeOffset, long lastTimecodeValueScalingFactor,
    byte[] emptyTimecode) {
  byte[] timeCodeData;
  if (durationUs == C.TIME_UNSET) {
    timeCodeData = emptyTimecode;
  } else {
    int hours = (int) (durationUs / (3600 * C.MICROS_PER_SECOND));
    durationUs -= (hours * 3600 * C.MICROS_PER_SECOND);
    int minutes = (int) (durationUs / (60 * C.MICROS_PER_SECOND));
    durationUs -= (minutes * 60 * C.MICROS_PER_SECOND);
    int seconds = (int) (durationUs / C.MICROS_PER_SECOND);
    durationUs -= (seconds * C.MICROS_PER_SECOND);
    int lastValue = (int) (durationUs / lastTimecodeValueScalingFactor);
    timeCodeData = Util.getUtf8Bytes(String.format(Locale.US, timecodeFormat, hours, minutes,
        seconds, lastValue));
  }
  System.arraycopy(timeCodeData, 0, subripSampleData, endTimecodeOffset, emptyTimecode.length);
}
 
Example 6
Source File: MatroskaExtractor.java    From K-Sonic with MIT License 6 votes vote down vote up
private static void setSubripSampleEndTimecode(byte[] subripSampleData, long timeUs) {
  byte[] timeCodeData;
  if (timeUs == C.TIME_UNSET) {
    timeCodeData = SUBRIP_TIMECODE_EMPTY;
  } else {
    int hours = (int) (timeUs / 3600000000L);
    timeUs -= (hours * 3600000000L);
    int minutes = (int) (timeUs / 60000000);
    timeUs -= (minutes * 60000000);
    int seconds = (int) (timeUs / 1000000);
    timeUs -= (seconds * 1000000);
    int milliseconds = (int) (timeUs / 1000);
    timeCodeData = Util.getUtf8Bytes(String.format(Locale.US, "%02d:%02d:%02d,%03d", hours,
        minutes, seconds, milliseconds));
  }
  System.arraycopy(timeCodeData, 0, subripSampleData, SUBRIP_PREFIX_END_TIMECODE_OFFSET,
      SUBRIP_TIMECODE_LENGTH);
}
 
Example 7
Source File: DataSchemeDataSource.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@Override
public long open(DataSpec dataSpec) throws IOException {
  transferInitializing(dataSpec);
  this.dataSpec = dataSpec;
  readPosition = (int) dataSpec.position;
  Uri uri = dataSpec.uri;
  String scheme = uri.getScheme();
  if (!SCHEME_DATA.equals(scheme)) {
    throw new ParserException("Unsupported scheme: " + scheme);
  }
  String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
  if (uriParts.length != 2) {
    throw new ParserException("Unexpected URI format: " + uri);
  }
  String dataString = uriParts[1];
  if (uriParts[0].contains(";base64")) {
    try {
      data = Base64.decode(dataString, 0);
    } catch (IllegalArgumentException e) {
      throw new ParserException("Error while parsing Base64 encoded string: " + dataString, e);
    }
  } else {
    // TODO: Add support for other charsets.
    data = Util.getUtf8Bytes(URLDecoder.decode(dataString, C.ASCII_NAME));
  }
  endPosition =
      dataSpec.length != C.LENGTH_UNSET ? (int) dataSpec.length + readPosition : data.length;
  if (endPosition > data.length || readPosition > endPosition) {
    data = null;
    throw new DataSourceException(DataSourceException.POSITION_OUT_OF_RANGE);
  }
  transferStarted(dataSpec);
  return (long) endPosition - readPosition;
}
 
Example 8
Source File: ClearKeyUtil.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey request data obtained from the Android ClearKey CDM to be spec compliant.
 *
 * @param request The request data.
 * @return The adjusted request data.
 */
public static byte[] adjustRequestData(byte[] request) {
  if (Util.SDK_INT >= 27) {
    return request;
  }
  // Prior to O-MR1 the ClearKey CDM encoded the values in the "kids" array using Base64 encoding
  // rather than Base64Url encoding. See [Internal: b/64388098]. We know the exact request format
  // from the platform's InitDataParser.cpp. Since there aren't any "+" or "/" symbols elsewhere
  // in the request, it's safe to fix the encoding by replacement through the whole request.
  String requestString = Util.fromUtf8Bytes(request);
  return Util.getUtf8Bytes(base64ToBase64Url(requestString));
}
 
Example 9
Source File: ClearKeyUtil.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey response data to be suitable for providing to the Android ClearKey CDM.
 *
 * @param response The response data.
 * @return The adjusted response data.
 */
public static byte[] adjustResponseData(byte[] response) {
  if (Util.SDK_INT >= 27) {
    return response;
  }
  // Prior to O-MR1 the ClearKey CDM expected Base64 encoding rather than Base64Url encoding for
  // the "k" and "kid" strings. See [Internal: b/64388098]. We know that the ClearKey CDM only
  // looks at the k, kid and kty parameters in each key, so can ignore the rest of the response.
  try {
    JSONObject responseJson = new JSONObject(Util.fromUtf8Bytes(response));
    StringBuilder adjustedResponseBuilder = new StringBuilder("{\"keys\":[");
    JSONArray keysArray = responseJson.getJSONArray("keys");
    for (int i = 0; i < keysArray.length(); i++) {
      if (i != 0) {
        adjustedResponseBuilder.append(",");
      }
      JSONObject key = keysArray.getJSONObject(i);
      adjustedResponseBuilder.append("{\"k\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("k")));
      adjustedResponseBuilder.append("\",\"kid\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("kid")));
      adjustedResponseBuilder.append("\",\"kty\":\"");
      adjustedResponseBuilder.append(key.getString("kty"));
      adjustedResponseBuilder.append("\"}");
    }
    adjustedResponseBuilder.append("]}");
    return Util.getUtf8Bytes(adjustedResponseBuilder.toString());
  } catch (JSONException e) {
    Log.e(TAG, "Failed to adjust response data: " + Util.fromUtf8Bytes(response), e);
    return response;
  }
}
 
Example 10
Source File: ClearKeyUtil.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey request data obtained from the Android ClearKey CDM to be spec compliant.
 *
 * @param request The request data.
 * @return The adjusted request data.
 */
public static byte[] adjustRequestData(byte[] request) {
  if (Util.SDK_INT >= 27) {
    return request;
  }
  // Prior to O-MR1 the ClearKey CDM encoded the values in the "kids" array using Base64 encoding
  // rather than Base64Url encoding. See [Internal: b/64388098]. We know the exact request format
  // from the platform's InitDataParser.cpp. Since there aren't any "+" or "/" symbols elsewhere
  // in the request, it's safe to fix the encoding by replacement through the whole request.
  String requestString = Util.fromUtf8Bytes(request);
  return Util.getUtf8Bytes(base64ToBase64Url(requestString));
}
 
Example 11
Source File: DataSchemeDataSource.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
@Override
public long open(DataSpec dataSpec) throws IOException {
  transferInitializing(dataSpec);
  this.dataSpec = dataSpec;
  readPosition = (int) dataSpec.position;
  Uri uri = dataSpec.uri;
  String scheme = uri.getScheme();
  if (!SCHEME_DATA.equals(scheme)) {
    throw new ParserException("Unsupported scheme: " + scheme);
  }
  String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
  if (uriParts.length != 2) {
    throw new ParserException("Unexpected URI format: " + uri);
  }
  String dataString = uriParts[1];
  if (uriParts[0].contains(";base64")) {
    try {
      data = Base64.decode(dataString, 0);
    } catch (IllegalArgumentException e) {
      throw new ParserException("Error while parsing Base64 encoded string: " + dataString, e);
    }
  } else {
    // TODO: Add support for other charsets.
    data = Util.getUtf8Bytes(URLDecoder.decode(dataString, C.ASCII_NAME));
  }
  endPosition =
      dataSpec.length != C.LENGTH_UNSET ? (int) dataSpec.length + readPosition : data.length;
  if (endPosition > data.length || readPosition > endPosition) {
    data = null;
    throw new DataSourceException(DataSourceException.POSITION_OUT_OF_RANGE);
  }
  transferStarted(dataSpec);
  return (long) endPosition - readPosition;
}
 
Example 12
Source File: ClearKeyUtil.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey response data to be suitable for providing to the Android ClearKey CDM.
 *
 * @param response The response data.
 * @return The adjusted response data.
 */
public static byte[] adjustResponseData(byte[] response) {
  if (Util.SDK_INT >= 27) {
    return response;
  }
  // Prior to O-MR1 the ClearKey CDM expected Base64 encoding rather than Base64Url encoding for
  // the "k" and "kid" strings. See [Internal: b/64388098]. We know that the ClearKey CDM only
  // looks at the k, kid and kty parameters in each key, so can ignore the rest of the response.
  try {
    JSONObject responseJson = new JSONObject(Util.fromUtf8Bytes(response));
    StringBuilder adjustedResponseBuilder = new StringBuilder("{\"keys\":[");
    JSONArray keysArray = responseJson.getJSONArray("keys");
    for (int i = 0; i < keysArray.length(); i++) {
      if (i != 0) {
        adjustedResponseBuilder.append(",");
      }
      JSONObject key = keysArray.getJSONObject(i);
      adjustedResponseBuilder.append("{\"k\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("k")));
      adjustedResponseBuilder.append("\",\"kid\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("kid")));
      adjustedResponseBuilder.append("\",\"kty\":\"");
      adjustedResponseBuilder.append(key.getString("kty"));
      adjustedResponseBuilder.append("\"}");
    }
    adjustedResponseBuilder.append("]}");
    return Util.getUtf8Bytes(adjustedResponseBuilder.toString());
  } catch (JSONException e) {
    Log.e(TAG, "Failed to adjust response data: " + Util.fromUtf8Bytes(response), e);
    return response;
  }
}
 
Example 13
Source File: ClearKeyUtil.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey request data obtained from the Android ClearKey CDM to be spec compliant.
 *
 * @param request The request data.
 * @return The adjusted request data.
 */
public static byte[] adjustRequestData(byte[] request) {
  if (Util.SDK_INT >= 27) {
    return request;
  }
  // Prior to O-MR1 the ClearKey CDM encoded the values in the "kids" array using Base64 encoding
  // rather than Base64Url encoding. See [Internal: b/64388098]. We know the exact request format
  // from the platform's InitDataParser.cpp. Since there aren't any "+" or "/" symbols elsewhere
  // in the request, it's safe to fix the encoding by replacement through the whole request.
  String requestString = Util.fromUtf8Bytes(request);
  return Util.getUtf8Bytes(base64ToBase64Url(requestString));
}
 
Example 14
Source File: ClearKeyUtil.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey response data to be suitable for providing to the Android ClearKey CDM.
 *
 * @param response The response data.
 * @return The adjusted response data.
 */
public static byte[] adjustResponseData(byte[] response) {
  if (Util.SDK_INT >= 27) {
    return response;
  }
  // Prior to O-MR1 the ClearKey CDM expected Base64 encoding rather than Base64Url encoding for
  // the "k" and "kid" strings. See [Internal: b/64388098]. We know that the ClearKey CDM only
  // looks at the k, kid and kty parameters in each key, so can ignore the rest of the response.
  try {
    JSONObject responseJson = new JSONObject(Util.fromUtf8Bytes(response));
    StringBuilder adjustedResponseBuilder = new StringBuilder("{\"keys\":[");
    JSONArray keysArray = responseJson.getJSONArray("keys");
    for (int i = 0; i < keysArray.length(); i++) {
      if (i != 0) {
        adjustedResponseBuilder.append(",");
      }
      JSONObject key = keysArray.getJSONObject(i);
      adjustedResponseBuilder.append("{\"k\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("k")));
      adjustedResponseBuilder.append("\",\"kid\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("kid")));
      adjustedResponseBuilder.append("\",\"kty\":\"");
      adjustedResponseBuilder.append(key.getString("kty"));
      adjustedResponseBuilder.append("\"}");
    }
    adjustedResponseBuilder.append("]}");
    return Util.getUtf8Bytes(adjustedResponseBuilder.toString());
  } catch (JSONException e) {
    Log.e(TAG, "Failed to adjust response data: " + Util.fromUtf8Bytes(response), e);
    return response;
  }
}
 
Example 15
Source File: ClearKeyUtil.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey request data obtained from the Android ClearKey CDM to be spec compliant.
 *
 * @param request The request data.
 * @return The adjusted request data.
 */
public static byte[] adjustRequestData(byte[] request) {
  if (Util.SDK_INT >= 27) {
    return request;
  }
  // Prior to O-MR1 the ClearKey CDM encoded the values in the "kids" array using Base64 encoding
  // rather than Base64Url encoding. See [Internal: b/64388098]. We know the exact request format
  // from the platform's InitDataParser.cpp. Since there aren't any "+" or "/" symbols elsewhere
  // in the request, it's safe to fix the encoding by replacement through the whole request.
  String requestString = Util.fromUtf8Bytes(request);
  return Util.getUtf8Bytes(base64ToBase64Url(requestString));
}
 
Example 16
Source File: ClearKeyUtil.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey response data to be suitable for providing to the Android ClearKey CDM.
 *
 * @param response The response data.
 * @return The adjusted response data.
 */
public static byte[] adjustResponseData(byte[] response) {
  if (Util.SDK_INT >= 27) {
    return response;
  }
  // Prior to O-MR1 the ClearKey CDM expected Base64 encoding rather than Base64Url encoding for
  // the "k" and "kid" strings. See [Internal: b/64388098]. We know that the ClearKey CDM only
  // looks at the k, kid and kty parameters in each key, so can ignore the rest of the response.
  try {
    JSONObject responseJson = new JSONObject(Util.fromUtf8Bytes(response));
    StringBuilder adjustedResponseBuilder = new StringBuilder("{\"keys\":[");
    JSONArray keysArray = responseJson.getJSONArray("keys");
    for (int i = 0; i < keysArray.length(); i++) {
      if (i != 0) {
        adjustedResponseBuilder.append(",");
      }
      JSONObject key = keysArray.getJSONObject(i);
      adjustedResponseBuilder.append("{\"k\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("k")));
      adjustedResponseBuilder.append("\",\"kid\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("kid")));
      adjustedResponseBuilder.append("\",\"kty\":\"");
      adjustedResponseBuilder.append(key.getString("kty"));
      adjustedResponseBuilder.append("\"}");
    }
    adjustedResponseBuilder.append("]}");
    return Util.getUtf8Bytes(adjustedResponseBuilder.toString());
  } catch (JSONException e) {
    Log.e(TAG, "Failed to adjust response data: " + Util.fromUtf8Bytes(response), e);
    return response;
  }
}
 
Example 17
Source File: ClearKeyUtil.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey request data obtained from the Android ClearKey CDM to be spec compliant.
 *
 * @param request The request data.
 * @return The adjusted request data.
 */
public static byte[] adjustRequestData(byte[] request) {
  if (Util.SDK_INT >= 27) {
    return request;
  }
  // Prior to O-MR1 the ClearKey CDM encoded the values in the "kids" array using Base64 encoding
  // rather than Base64Url encoding. See [Internal: b/64388098]. We know the exact request format
  // from the platform's InitDataParser.cpp. Since there aren't any "+" or "/" symbols elsewhere
  // in the request, it's safe to fix the encoding by replacement through the whole request.
  String requestString = Util.fromUtf8Bytes(request);
  return Util.getUtf8Bytes(base64ToBase64Url(requestString));
}
 
Example 18
Source File: DataSchemeDataSource.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
public long open(DataSpec dataSpec) throws IOException {
  transferInitializing(dataSpec);
  this.dataSpec = dataSpec;
  readPosition = (int) dataSpec.position;
  Uri uri = dataSpec.uri;
  String scheme = uri.getScheme();
  if (!SCHEME_DATA.equals(scheme)) {
    throw new ParserException("Unsupported scheme: " + scheme);
  }
  String[] uriParts = Util.split(uri.getSchemeSpecificPart(), ",");
  if (uriParts.length != 2) {
    throw new ParserException("Unexpected URI format: " + uri);
  }
  String dataString = uriParts[1];
  if (uriParts[0].contains(";base64")) {
    try {
      data = Base64.decode(dataString, 0);
    } catch (IllegalArgumentException e) {
      throw new ParserException("Error while parsing Base64 encoded string: " + dataString, e);
    }
  } else {
    // TODO: Add support for other charsets.
    data = Util.getUtf8Bytes(URLDecoder.decode(dataString, C.ASCII_NAME));
  }
  endPosition =
      dataSpec.length != C.LENGTH_UNSET ? (int) dataSpec.length + readPosition : data.length;
  if (endPosition > data.length || readPosition > endPosition) {
    data = null;
    throw new DataSourceException(DataSourceException.POSITION_OUT_OF_RANGE);
  }
  transferStarted(dataSpec);
  return (long) endPosition - readPosition;
}
 
Example 19
Source File: ClearKeyUtil.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Adjusts ClearKey response data to be suitable for providing to the Android ClearKey CDM.
 *
 * @param response The response data.
 * @return The adjusted response data.
 */
public static byte[] adjustResponseData(byte[] response) {
  if (Util.SDK_INT >= 27) {
    return response;
  }
  // Prior to O-MR1 the ClearKey CDM expected Base64 encoding rather than Base64Url encoding for
  // the "k" and "kid" strings. See [Internal: b/64388098]. We know that the ClearKey CDM only
  // looks at the k, kid and kty parameters in each key, so can ignore the rest of the response.
  try {
    JSONObject responseJson = new JSONObject(Util.fromUtf8Bytes(response));
    StringBuilder adjustedResponseBuilder = new StringBuilder("{\"keys\":[");
    JSONArray keysArray = responseJson.getJSONArray("keys");
    for (int i = 0; i < keysArray.length(); i++) {
      if (i != 0) {
        adjustedResponseBuilder.append(",");
      }
      JSONObject key = keysArray.getJSONObject(i);
      adjustedResponseBuilder.append("{\"k\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("k")));
      adjustedResponseBuilder.append("\",\"kid\":\"");
      adjustedResponseBuilder.append(base64UrlToBase64(key.getString("kid")));
      adjustedResponseBuilder.append("\",\"kty\":\"");
      adjustedResponseBuilder.append(key.getString("kty"));
      adjustedResponseBuilder.append("\"}");
    }
    adjustedResponseBuilder.append("]}");
    return Util.getUtf8Bytes(adjustedResponseBuilder.toString());
  } catch (JSONException e) {
    Log.e(TAG, "Failed to adjust response data: " + Util.fromUtf8Bytes(response), e);
    return response;
  }
}