info: additional info for video streams
This commit is contained in:
parent
b60ebf6698
commit
a2dec02a14
3 changed files with 93 additions and 3 deletions
66
lib/model/video/h264.dart
Normal file
66
lib/model/video/h264.dart
Normal file
|
@ -0,0 +1,66 @@
|
|||
class H264 {
|
||||
static const profileConstrained = 1 << 9;
|
||||
static const profileIntra = 1 << 11;
|
||||
static const profileBaseline = 66;
|
||||
static const profileConstrainedBaseline = 66 | profileConstrained;
|
||||
static const profileMain = 77;
|
||||
static const profileExtended = 88;
|
||||
static const profileHigh = 100;
|
||||
static const profileHigh10 = 110;
|
||||
static const profileHigh10Intra = 110 | profileIntra;
|
||||
static const profileHigh422 = 122;
|
||||
static const profileHigh422Intra = 122 | profileIntra;
|
||||
static const profileHigh444 = 144;
|
||||
static const profileHigh444Predictive = 244;
|
||||
static const profileHigh444Intra = 244 | profileIntra;
|
||||
static const profileCAVLC_444 = 44;
|
||||
|
||||
static String formatProfile(int profileIndex, int level) {
|
||||
String profile;
|
||||
switch (profileIndex) {
|
||||
case profileBaseline:
|
||||
profile = 'Baseline';
|
||||
break;
|
||||
case profileConstrainedBaseline:
|
||||
profile = 'Constrained Baseline';
|
||||
break;
|
||||
case profileMain:
|
||||
profile = 'Main';
|
||||
break;
|
||||
case profileExtended:
|
||||
profile = 'Extended';
|
||||
break;
|
||||
case profileHigh:
|
||||
profile = 'High';
|
||||
break;
|
||||
case profileHigh10:
|
||||
profile = 'High 10';
|
||||
break;
|
||||
case profileHigh10Intra:
|
||||
profile = 'High 10 Intra';
|
||||
break;
|
||||
case profileHigh422:
|
||||
profile = 'High 4:2:2';
|
||||
break;
|
||||
case profileHigh422Intra:
|
||||
profile = 'High 4:2:2 Intra';
|
||||
break;
|
||||
case profileHigh444:
|
||||
profile = 'High 4:4:4';
|
||||
break;
|
||||
case profileHigh444Predictive:
|
||||
profile = 'High 4:4:4 Predictive';
|
||||
break;
|
||||
case profileHigh444Intra:
|
||||
profile = 'High 4:4:4 Intra';
|
||||
break;
|
||||
case profileCAVLC_444:
|
||||
profile = 'CAVLC 4:4:4';
|
||||
break;
|
||||
default:
|
||||
return '$profileIndex';
|
||||
}
|
||||
if (level < 10) return profile;
|
||||
return '$profile Profile, Level ${level % 10 == 0 ? level ~/ 10 : level / 10}';
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
|
||||
import 'package:aves/model/entry.dart';
|
||||
import 'package:aves/model/video/channel_layouts.dart';
|
||||
import 'package:aves/model/video/h264.dart';
|
||||
import 'package:aves/ref/languages.dart';
|
||||
import 'package:aves/utils/math_utils.dart';
|
||||
import 'package:fijkplayer/fijkplayer.dart';
|
||||
|
@ -9,7 +10,12 @@ import 'package:fijkplayer/fijkplayer.dart';
|
|||
class StreamInfo {
|
||||
static const keyBitrate = 'bitrate';
|
||||
static const keyChannelLayout = 'channel_layout';
|
||||
static const keyCodecLevel = 'codec_level';
|
||||
static const keyCodecName = 'codec_name';
|
||||
static const keyCodecPixelFormat = 'codec_pixel_format';
|
||||
static const keyCodecProfileId = 'codec_profile_id';
|
||||
static const keyDurationMicro = 'duration_us';
|
||||
static const keyFormat = 'format';
|
||||
static const keyFpsDen = 'fps_den';
|
||||
static const keyFpsNum = 'fps_num';
|
||||
static const keyHeight = 'height';
|
||||
|
@ -18,6 +24,7 @@ class StreamInfo {
|
|||
static const keySampleRate = 'sample_rate';
|
||||
static const keySarDen = 'sar_den';
|
||||
static const keySarNum = 'sar_num';
|
||||
static const keyStartMicro = 'start_us';
|
||||
static const keyTbrDen = 'tbr_den';
|
||||
static const keyTbrNum = 'tbr_num';
|
||||
static const keyType = 'type';
|
||||
|
@ -72,13 +79,16 @@ class StreamInfo {
|
|||
|
||||
static Map<String, String> formatStreamInfo(Map stream) {
|
||||
final dir = <String, String>{};
|
||||
final type = stream[keyType];
|
||||
final codec = stream[keyCodecName];
|
||||
for (final kv in stream.entries) {
|
||||
final value = kv.value;
|
||||
if (value != null) {
|
||||
final key = kv.key;
|
||||
switch (key) {
|
||||
case keyIndex:
|
||||
case keyCodecLevel:
|
||||
case keyFpsNum:
|
||||
case keyIndex:
|
||||
case keySarNum:
|
||||
case keyTbrNum:
|
||||
case keyTbrDen:
|
||||
|
@ -91,7 +101,21 @@ class StreamInfo {
|
|||
dir['Channel Layout'] = ChannelLayouts.names[value] ?? 'unknown ($value)';
|
||||
break;
|
||||
case keyCodecName:
|
||||
dir['Codec'] = _getCodecName(value);
|
||||
dir['Codec'] = _getCodecName(value as String);
|
||||
break;
|
||||
case keyCodecPixelFormat:
|
||||
if (type == typeVideo) {
|
||||
dir['Pixel Format'] = (value as String).toUpperCase();
|
||||
}
|
||||
break;
|
||||
case keyCodecProfileId:
|
||||
if (codec == 'h264') {
|
||||
final profile = int.tryParse(value as String);
|
||||
if (profile != null && profile != 0) {
|
||||
final level = int.tryParse(stream[keyCodecLevel] as String);
|
||||
dir['Codec Profile'] = H264.formatProfile(profile, level);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case keyFpsDen:
|
||||
dir['Frame Rate'] = roundToPrecision(stream[keyFpsNum] / stream[keyFpsDen], decimals: 3).toString();
|
||||
|
|
|
@ -211,7 +211,7 @@ packages:
|
|||
description:
|
||||
path: "."
|
||||
ref: aves
|
||||
resolved-ref: "118fa08b30a7948df04d2692649b124a09ccb480"
|
||||
resolved-ref: c217373cfe61fb17941571d17e38236765a8ec07
|
||||
url: "git://github.com/deckerst/fijkplayer.git"
|
||||
source: git
|
||||
version: "0.8.7"
|
||||
|
|
Loading…
Reference in a new issue