#c# #linq #lambda #ffmpeg
#c# #linq #lambda #ffmpeg
Вопрос:
со вчерашнего дня я пытался реализовать ffmpeg через Xabe-Wrapper в моем C #-проекте. Я использовал FFMpeg => FFProbe для получения форматирования и потоковой передачи данных в виде json-строки из некоторых фильмов. Это json, который я получил для потоков.
"{
"streams": [
{"codec_name": "mpeg4", "codec_type": "video"},
{"codec_name": "mp3" , "codec_type": "audio"}
]
}"
Следуя Newtonsoft Wiki, я десериализовал его как DataSet. Я начал играть и нашел способ сделать это в «oneliner».
Streams = (JsonConvert.DeserializeObject<DataSet>(StreamProbeJSON,
JSerializerSettings)).Tables["streams"].AsEnumerable().Select(value => new
FormatAVInfo.SInfo(value.Field<string>("codec_type"), value.Field<string>
("codec_name")));
Для формата я получаю этот Json
{
"format": {
"format_name": "avi",
"probe_score": 100
}
}
Следуя Newtonsoft Wiki, я десериализовал этот объект как словарь, но я не в состоянии снова сделать это в oneliner. Это не большая проблема, но я хотел бы узнать, как я могу этого добиться?
Я попробовал это
Format = (JsonConvert.DeserializeObject<Dictionary<string,
Dictionary<string, string>>>(FormatProbeJSON, JSerializerSettings))
["format"].Select(value => new FormatAVInfo.FInfo(value["format_name"],
value["probe_score"]));
Но, конечно, я получаю KeyValuePair и не могу использовать индексатор для этого. Я также пробовал с помощью JObject, с тем же результатом. Конечно, я мог бы просто создать другое поле
Dictionary<string,string> Temp =
(JsonConvert.DeserializeObject<Dictionary<string,
Dictionary<string, string>>>(FormatProbeJSON, JSerializerSettings))
["format"]
И создать экземпляр впоследствии, но мне любопытно, есть ли способ сделать это.
Спасибо
Комментарии:
1. Почему вы не десериализуете его в реальную модель вместо словарей? Тогда это просто
JsonConvert.DeserializeObject<MyModel>(json)
это хорошая и короткая строка.2. Я немного аутист, и мне не нравятся имена полей, которые я не могу переименовать. Я не знаю, есть ли для этого что-то вроде DataContracts.
3. Вы можете использовать [JsonPropertyAttribute] для переименования полей. например,
[JsonProperty("format_name")] public string ThisIsTheFormatName { get; set; }
и JsonConvert отобразит это.4. Спасибо, эта работа завершена. Теперь я счастлив. Единственная проблема сейчас в том, что я действительно теперь знаю, как заставить это сериализоваться в Dictionary<string, foo> . Я должен использовать атрибут JsonArrayAttribute, верно? Но большое вам спасибо
Ответ №1:
Вы должны десериализовать этот тип данных в модель, а не в Dictionary
, поскольку, похоже, у него фиксированная структура, а не динамическая.
Например, давайте назовем модель «MyMovieData».
public class MyMovieData
{
[JsonProperty("streams"]
public MovieStream[] Streams { get; set; }
}
public class MovieStream[]
{
[JsonProperty("codec_name")]
public string CodecName { get; set; }
[JsonProperty("codec_type")]
public string CodecType { get; set; }
}
Теперь вы можете десериализовать его очень простым способом:
MyMovieData bigBuckBunnyData = JsonConvert.DeserializeObject<MyMovieData>(json);
MovieStream[] bigBuckBunnyStreams = bigBuckBunnyData.Streams;
Комментарии:
1. Да, спасибо, это работает. Я просто надеялся, что он будет в списке с «Video1» => { Type и т.д.}, А не в массиве. Но это абсолютно нормально
2. Тогда вы можете сделать
JsonConvert.DeserializeObject<MyMovieData[]>(json)
, если у вас есть массив данных.<List<MyMovieData>>(json)
Если вы предпочитаетеList<>
.