/
nuvinfo
executable file
·154 lines (144 loc) · 4.74 KB
/
nuvinfo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/perl -w
#Last Updated: 2003.00.00 (xris)
#nuvinfo.pl
$file = '/var/video/1059_20030516200000_20030516210000.nuv';
$file = $ARGV[0] if ($ARGV[0]);
my %info = nuv_info($file);
print "\n\ninfo for: $file\n\n";
foreach $key (sort keys %info) {
print "$key: $info{$key}\n";
}
print "\ndone\n\n";
sub mpeg_info {
my $file = shift;
$file =~ s/'/\\'/sg;
my %info;
# First, we check for the existence of an mpeg info program
my $program = find_program('mpgtx', 'tcprobe');
# Nothing found? Die
die "You need tcprobe (transcode) or mpgtx to use this script on mpeg-based nuv files.\n\n" unless ($program);
# Grab tcprobe info
if ($program =~ /tcprobe$/) {
my $data = `$program -i '$file'`;
($info{width}, $info{height}) = $data =~ /frame\s+size:\s+-g\s+(\d+)x(\d+)\b/m;
($info{fps}) = $data =~ /frame\s+rate:\s+-f\s+(\d+(?:\.\s+)?)\b/m;
($info{audio_sample_rate}) = $data =~ /audio\s+track:.+?-e\s+(\d+)\b/m;
}
# Grab tcmplex info
elsif ($program =~ /mpgtx$/) {
my $data = `$program -i '$file'`;
($info{width}, $info{height}, $info{fps}) = $data =~ /\bSize\s+\[(\d+)\s*x\s*(\d+)\]\s+(\d+(?:\.\d+)?)\s*fps/m;
($info{audio_sample_rate}) = $data =~ /\b(\d+)\s*Hz/m;
}
# Return
return %info;
}
# This searches the path for the specified programs, and returns the lowest-index-value program found
sub find_program {
# Load the programs, and get a count of the priorities
my(%programs, $num_programs);
foreach my $program (@_) {
$programs{$program} = ++$num_programs;
}
# No programs requested?
return undef unless ($num_programs > 0);
# Search for the program(s)
my %found;
foreach my $path (split(/:/, $ENV{PATH}), '.') {
foreach my $program (keys %programs) {
if (-e "$path/$program" && (!$found{name} || $programs{$program} < $programs{$found{name}})) {
$found{name} = $program;
$found{path} = $path;
}
# Leave early if we found the highest priority program
last if ($found{name} && $programs{$found{name}} == 1);
}
}
# Return
return undef unless ($found{path} && $found{name});
return $found{path}.'/'.$found{name};
}
# Opens a .nuv file and returns information about it
sub nuv_info {
my $file = shift;
my(%info, $buffer);
# open the file
open(DATA, $file) or die "Can't open $file: $!\n\n";
# Read the file info header
read(DATA, $buffer, 72);
# Unpack the data structure
($info{finfo}, # "NuppelVideo" + \0
$info{version}, # "0.05" + \0
$info{width},
$info{height},
$info{desiredheight}, # 0 .. as it is
$info{desiredwidth}, # 0 .. as it is
$info{pimode}, # P .. progressive, I .. interlaced (2 half pics) [NI]
$info{aspect}, # 1.0 .. square pixel (1.5 .. e.g. width=480: width*1.5=720 for capturing for svcd material
$info{fps},
$info{videoblocks}, # count of video-blocks -1 .. unknown 0 .. no video
$info{audioblocks}, # count of audio-blocks -1 .. unknown 0 .. no audio
$info{textsblocks}, # count of text-blocks -1 .. unknown 0 .. no text
$info{keyframedist}
) = unpack('Z12 Z5 xxx i i i i a xxx d d i i i i', $buffer);
# Is this even a NUV file?
return mpeg_info($file) unless ($info{finfo} =~ /\w/);
# Perl occasionally over-reads on the previous read()
seek(DATA, 72, 0);
# Read and parse the first frame header
read(DATA, $buffer, 12);
my ($frametype,
$comptype,
$keyframe,
$filters,
$timecode,
$packetlength) = unpack('a a a a i i', $buffer);
# Parse the frame
die "Illegal nuv file format: $file\n\n" unless ($frametype eq 'D');
# Read some more stuff if we have to
read(DATA, $buffer, $packetlength) if ($packetlength);
# Read the remaining frame headers
while (12 == read(DATA, $buffer, 12)) {
# Parse the frame header
($frametype,
$comptype,
$keyframe,
$filters,
$timecode,
$packetlength) = unpack('a a a a i i', $buffer);
# Read some more stuff if we have to
read(DATA, $buffer, $packetlength) if ($packetlength);
# Look for the audio frame
if ($frametype eq 'X') {
my $frame_version;
($frame_version,
$info{video_fourcc},
$info{audio_fourcc},
$info{audio_sample_rate},
$info{audio_bits_per_sample},
$info{audio_channels},
$info{audio_compression_ratio},
$info{audio_quality},
$info{rtjpeg_quality},
$info{rtjpeg_luma_filter},
$info{rtjpeg_chroma_filter},
$info{lavc_bitrate},
$info{lavc_qmin},
$info{lavc_qmax},
$info{lavc_maxqdiff},
$info{seektable_offset},
$info{keyframeadjust_offset}
) = unpack('iiiiiiiiiiiiiiill', $buffer);
# Found the audio data we want - time to leave
last;
}
# Done reading frames - let's leave
else {
last;
}
}
# Close the file
close DATA;
# Return
return %info;
}