I started writing the Java library Brockman to parse a JSON response similar to this example using Moshi. However, the format requires to generalize a bit for the stream
objects.
The video stream excerpt:
{
"slug": "hd-native",
"display": "Saal 1 FullHD Video",
"type": "video",
"isTranslated": false,
"videoSize": [
1920,
1080
],
"urls": {
"webm": {
"display": "WebM",
"tech": "1920x1080, VP8+Vorbis in WebM, 2.8 MBit/s",
"url": "http://example.com/s1_native_hd.webm"
},
"hls": {
"display": "HLS",
"tech": "1920x1080, h264+AAC im MPEG-TS-Container via HTTP",
"url": "http://example.com/hls/s1_native_hd.m3u8"
}
}
}
The audio stream excerpt:
{
"slug": "audio-native",
"display": "Saal 1 Audio",
"type": "audio",
"isTranslated": false,
"videoSize": null,
"urls": {
"mp3": {
"display": "MP3",
"tech": "MP3-Audio, 96 kBit/s",
"url": "http://example.com/s1_native.mp3"
},
"opus": {
"display": "Opus",
"tech": "Opus-Audio, 64 kBit/s",
"url": "http://example.com/s1_native.opus"
}
}
}
The content of the urls = {}
object differs dependent on whether the stream
type
is video
or audio
as one can see from the examples above.
Currently, there are only the models Mp3
and Opus
which are identical by their properties. I would like to substitute them with a Format
class which could also act as a replacement for the missing Webm
and Hls
classes. How can I actually map the different fields of the Urls
object into the Format
class?
public class Format {
public final String display;
public final String tech;
public final String url;
public Format(String display, String tech, String url) {
this.display = display;
this.tech = tech;
this.url = url;
}
}
I could imagine that the Stream
class would look something like this:
public class Stream {
public final String display;
public final boolean isTranslated;
public final String slug;
public final String type;
public final VideoSize videoSize;
public final List<Format> urls; // How to map into List<Format>?
// ...
I came up with the following:
public class StreamAdapter {
@ToJson
public String toJson(Stream stream) throws Exception {
throw new UnsupportedOperationException("Not yet implemented.");
}
@FromJson
public Stream fromJson(StreamJson streamJson) throws Exception {
String slug = streamJson.slug;
String display = streamJson.display;
boolean isTranslated = streamJson.isTranslated;
Stream.TYPE type = streamJson.type;
VideoSize videoSize = streamJson.videoSize;
Map<String, Object> urlsJson = streamJson.urls;
List<Url> urls = getUrls(urlsJson);
return new Stream(display, isTranslated, slug, type, videoSize, urls);
}
private List<Url> getUrls(Map<String, Object> urlsJson) {
Set<String> urlTypes = urlsJson.keySet();
List<Url> urls = new ArrayList<Url>(urlTypes.size());
for (String urlType : urlTypes) {
@SuppressWarnings("unchecked")
Map<String, String> urlProperties = (Map<String, String>) urlsJson.get(urlType);
urls.add(getUrl(urlType, urlProperties));
}
return urls;
}
private Url getUrl(String urlType, Map<String, String> properties) {
Url.TYPE type = new UrlTypeAdapter().fromJson(urlType);
String display = properties.get("display");
String tech = properties.get("tech");
String url = properties.get("url");
return new Url(type, display, tech, url);
}
private static final class StreamJson {
String slug;
String display;
boolean isTranslated;
Stream.TYPE type;
VideoSize videoSize;
Map<String, Object> urls;
}
}
Note that I use an Url
class now instead of the Format
class mentioned in the question. Please find more details here. If you have ideas on how to improve this you are welcome to comment here or create an issue/pull request on the repository.