mxfinfo 0.0.3.6 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,194 @@
1
+ /*
2
+ * Parse metadata from an Avid MXF file
3
+ *
4
+ * Copyright (C) 2008, British Broadcasting Corporation
5
+ * All Rights Reserved.
6
+ *
7
+ * Author: Philip de Nier
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions are met:
11
+ *
12
+ * * Redistributions of source code must retain the above copyright notice,
13
+ * this list of conditions and the following disclaimer.
14
+ * * Redistributions in binary form must reproduce the above copyright
15
+ * notice, this list of conditions and the following disclaimer in the
16
+ * documentation and/or other materials provided with the distribution.
17
+ * * Neither the name of the British Broadcasting Corporation nor the names
18
+ * of its contributors may be used to endorse or promote products derived
19
+ * from this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
+ * POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+
34
+ #ifndef __AVID_MXF_INFO_H__
35
+ #define __AVID_MXF_INFO_H__
36
+
37
+
38
+ #ifdef __cplusplus
39
+ extern "C"
40
+ {
41
+ #endif
42
+
43
+
44
+ #include <mxf/mxf_types.h>
45
+
46
+
47
+ /* Note: keep get_essence_type_string() in sync when changes are made here */
48
+ typedef enum
49
+ {
50
+ UNKNOWN_ESSENCE_TYPE = 0,
51
+ MPEG_30_ESSENCE_TYPE,
52
+ MPEG_40_ESSENCE_TYPE,
53
+ MPEG_50_ESSENCE_TYPE,
54
+ DV_25_411_ESSENCE_TYPE,
55
+ DV_25_420_ESSENCE_TYPE,
56
+ DV_50_ESSENCE_TYPE,
57
+ DV_100_ESSENCE_TYPE,
58
+ MJPEG_20_1_ESSENCE_TYPE,
59
+ MJPEG_2_1_S_ESSENCE_TYPE,
60
+ MJPEG_4_1_S_ESSENCE_TYPE,
61
+ MJPEG_15_1_S_ESSENCE_TYPE,
62
+ MJPEG_10_1_ESSENCE_TYPE,
63
+ MJPEG_10_1_M_ESSENCE_TYPE,
64
+ MJPEG_4_1_M_ESSENCE_TYPE,
65
+ MJPEG_3_1_ESSENCE_TYPE,
66
+ MJPEG_2_1_ESSENCE_TYPE,
67
+ UNC_1_1_ESSENCE_TYPE,
68
+ UNC_1_1_10B_ESSENCE_TYPE,
69
+ MJPEG_35_1_P_ESSENCE_TYPE,
70
+ MJPEG_28_1_P_ESSENCE_TYPE,
71
+ MJPEG_14_1_P_ESSENCE_TYPE,
72
+ MJPEG_3_1_P_ESSENCE_TYPE,
73
+ MJPEG_2_1_P_ESSENCE_TYPE,
74
+ MJPEG_3_1_M_ESSENCE_TYPE,
75
+ MJPEG_8_1_M_ESSENCE_TYPE,
76
+ DNXHD_1235_ESSENCE_TYPE,
77
+ DNXHD_1237_ESSENCE_TYPE,
78
+ DNXHD_1238_ESSENCE_TYPE,
79
+ DNXHD_1241_ESSENCE_TYPE,
80
+ DNXHD_1242_ESSENCE_TYPE,
81
+ DNXHD_1243_ESSENCE_TYPE,
82
+ DNXHD_1250_ESSENCE_TYPE,
83
+ DNXHD_1251_ESSENCE_TYPE,
84
+ DNXHD_1252_ESSENCE_TYPE,
85
+ DNXHD_1253_ESSENCE_TYPE,
86
+ MPEG4_ESSENCE_TYPE,
87
+ XDCAM_HD_ESSENCE_TYPE,
88
+ AVCINTRA_100_ESSENCE_TYPE,
89
+ AVCINTRA_50_ESSENCE_TYPE,
90
+ PCM_ESSENCE_TYPE
91
+ } AvidEssenceType;
92
+
93
+ typedef enum
94
+ {
95
+ UNKNOWN_PHYS_TYPE = 0,
96
+ TAPE_PHYS_TYPE,
97
+ IMPORT_PHYS_TYPE,
98
+ RECORDING_PHYS_TYPE
99
+ } AvidPhysicalPackageType;
100
+
101
+ typedef enum
102
+ {
103
+ FULL_FRAME_FRAME_LAYOUT = 0,
104
+ SEPARATE_FIELDS_FRAME_LAYOUT,
105
+ SINGLE_FIELD_FRAME_LAYOUT,
106
+ MIXED_FIELD_FRAME_LAYOUT,
107
+ SEGMENTED_FRAME_FRAME_LAYOUT,
108
+ } AvidFrameLayout;
109
+
110
+ typedef struct
111
+ {
112
+ char *name;
113
+ char *value;
114
+ } AvidNameValuePair;
115
+
116
+ typedef struct
117
+ {
118
+ char *name;
119
+ char *value;
120
+ AvidNameValuePair *attributes;
121
+ int numAttributes;
122
+ } AvidTaggedValue;
123
+
124
+ typedef struct
125
+ {
126
+ /* clip info */
127
+ char *clipName;
128
+ char *projectName;
129
+ mxfTimestamp clipCreated;
130
+ mxfRational projectEditRate;
131
+ int64_t clipDuration;
132
+ mxfUMID materialPackageUID;
133
+ AvidTaggedValue *userComments;
134
+ int numUserComments;
135
+ AvidTaggedValue *materialPackageAttributes;
136
+ int numMaterialPackageAttributes;
137
+ int numVideoTracks;
138
+ int numAudioTracks;
139
+ char *tracksString;
140
+
141
+ /* track info */
142
+ uint32_t trackNumber;
143
+ int isVideo;
144
+ mxfRational editRate;
145
+ int64_t trackDuration;
146
+ int64_t segmentDuration;
147
+ int64_t segmentOffset;
148
+ int64_t startTimecode;
149
+
150
+ /* file essence info */
151
+ AvidEssenceType essenceType;
152
+ mxfUMID fileSourcePackageUID;
153
+ mxfUL essenceContainerLabel;
154
+
155
+ /* picture info */
156
+ mxfUL pictureCodingLabel;
157
+ uint8_t frameLayout;
158
+ mxfRational aspectRatio;
159
+ uint32_t storedWidth;
160
+ uint32_t storedHeight;
161
+ uint32_t displayWidth;
162
+ uint32_t displayHeight;
163
+
164
+ /* sound info */
165
+ mxfRational audioSamplingRate;
166
+ uint32_t channelCount;
167
+ uint32_t quantizationBits;
168
+
169
+ /* physical source info */
170
+ char *physicalPackageName;
171
+ mxfUMID physicalSourcePackageUID;
172
+ AvidPhysicalPackageType physicalPackageType;
173
+ char *physicalPackageLocator;
174
+
175
+ } AvidMXFInfo;
176
+
177
+
178
+
179
+ int ami_read_info(const char *filename, AvidMXFInfo *info, int printDebugError);
180
+
181
+ void ami_free_info(AvidMXFInfo *info);
182
+
183
+ void ami_print_info(AvidMXFInfo *info);
184
+ /* TODO: add function to print machine readable info e.g. newline delimited fields */
185
+
186
+ const char* get_essence_type_string(AvidEssenceType essenceType, mxfRational editRate);
187
+
188
+ #ifdef __cplusplus
189
+ }
190
+ #endif
191
+
192
+
193
+ #endif
194
+
@@ -0,0 +1,12 @@
1
+ require 'mkmf'
2
+
3
+ unless pkg_config('libMXF-1.0')
4
+ raise "libMXF-1.0 could not be found!"
5
+ end
6
+
7
+ $warnflags = ''
8
+ $defs.push '--std=gnu99'
9
+ $defs.push '-D_GNU_SOURCE'
10
+ $defs.push '-Wall'
11
+
12
+ create_makefile('mxfinfo')
@@ -0,0 +1,313 @@
1
+ #include <time.h>
2
+ #include <ruby.h>
3
+ #include "avid_mxf_info.h"
4
+
5
+ /* Helpers. */
6
+
7
+ static
8
+ VALUE rb_time_from_mxf_timestamp(mxfTimestamp *ts)
9
+ {
10
+ /*
11
+ * NOTE: This is probably not thread-safe, since struct tm*
12
+ * returned by localtime is shared static.
13
+ */
14
+ time_t t;
15
+ time(&t);
16
+ struct tm *tmts;
17
+ tmts = localtime(&t);
18
+
19
+ tmts->tm_year = (int) ts->year - 1900;
20
+ tmts->tm_mon = (int) ts->month - 1;
21
+ tmts->tm_mday = (int) ts->day;
22
+ tmts->tm_hour = (int) ts->hour;
23
+ tmts->tm_min = (int) ts->min;
24
+ tmts->tm_sec = (int) ts->sec;
25
+
26
+ return rb_time_new(mktime(tmts), ts->qmsec);
27
+ }
28
+
29
+ static
30
+ VALUE rb_str_from_label(const unsigned char *lbl, int len)
31
+ {
32
+ char hex[len * 2 + 1];
33
+ for(int i = 0; i < len; i++)
34
+ {
35
+ sprintf(&hex[i * 2], "%02x", lbl[i]);
36
+ }
37
+ hex[len * 2 + 1] = '\0';
38
+ return rb_str_new2(hex);
39
+ }
40
+
41
+ /* Some macros. */
42
+
43
+ #define CIO_GENERIC_GETTER(cast, name, attr) \
44
+ static \
45
+ VALUE cio_get_##name (VALUE self) \
46
+ { \
47
+ AvidMXFInfo *info; \
48
+ Data_Get_Struct(self, AvidMXFInfo, info); \
49
+ return cast (info-> attr ); \
50
+ }
51
+
52
+ #define CIO_STRING_GETTER(name, attr) \
53
+ static \
54
+ VALUE cio_get_##name (VALUE self) \
55
+ { \
56
+ AvidMXFInfo *info; \
57
+ Data_Get_Struct(self, AvidMXFInfo, info); \
58
+ return ((info-> attr ) != NULL) ? rb_str_new2(info-> attr ) : Qnil; \
59
+ }
60
+
61
+ #define CIO_LABEL_GETTER(name, attr, len) \
62
+ static \
63
+ VALUE cio_get_##name (VALUE self) \
64
+ { \
65
+ AvidMXFInfo *info; \
66
+ Data_Get_Struct(self, AvidMXFInfo, info); \
67
+ return rb_str_from_label((unsigned char*) &( info-> attr ), len ); \
68
+ }
69
+
70
+ #define CIO_RATIONAL_GETTER(name, attr) \
71
+ static \
72
+ VALUE cio_get_##name (VALUE self) \
73
+ { \
74
+ AvidMXFInfo *info; \
75
+ Data_Get_Struct(self, AvidMXFInfo, info); \
76
+ return rb_rational_new(INT2FIX((info-> attr ).numerator), \
77
+ INT2FIX((info-> attr ).denominator)); \
78
+ }
79
+
80
+ #define CIO_INT_GETTER(name, attr) CIO_GENERIC_GETTER(INT2FIX, name, attr)
81
+ #define CIO_UINT_GETTER(name, attr) CIO_GENERIC_GETTER(UINT2NUM, name, attr)
82
+ #define CIO_INT64_GETTER(name, attr) CIO_GENERIC_GETTER(LL2NUM, name, attr)
83
+
84
+ /* Ruby API. */
85
+
86
+ VALUE m_mxfinfo = Qnil;
87
+ VALUE c_infoobject = Qnil;
88
+
89
+ static
90
+ void cio_free(void *ptr) {
91
+ ami_free_info(ptr);
92
+ }
93
+
94
+ static
95
+ VALUE cio_new(VALUE class, VALUE path)
96
+ {
97
+ Check_Type(path, T_STRING);
98
+ const char *fn = StringValuePtr(path);
99
+
100
+ AvidMXFInfo *info = ALLOC(AvidMXFInfo);
101
+
102
+ int result = ami_read_info(fn, info, 1);
103
+
104
+ if(result != 0)
105
+ {
106
+ ami_free_info(info);
107
+
108
+ switch(result)
109
+ {
110
+ case -2:
111
+ rb_raise(rb_eIOError, "Failed to open file.");
112
+ break;
113
+ case -3:
114
+ rb_raise(rb_eIOError, "Failed to read header partition.");
115
+ break;
116
+ case -4:
117
+ rb_raise(rb_eStandardError, "File is not OP-Atom.");
118
+ break;
119
+ case -1:
120
+ default:
121
+ rb_raise(rb_eStandardError, "Failed to read info.");
122
+ break;
123
+ }
124
+
125
+ return Qnil;
126
+ }
127
+ else
128
+ {
129
+ VALUE tdata = Data_Wrap_Struct(class, 0, cio_free, info);
130
+ return tdata;
131
+ }
132
+ }
133
+
134
+ /* Simple getters. */
135
+
136
+ CIO_STRING_GETTER(clip_name, clipName)
137
+ CIO_STRING_GETTER(project_name, projectName)
138
+ CIO_RATIONAL_GETTER(project_edit_rate, projectEditRate)
139
+ CIO_INT64_GETTER(clip_duration, clipDuration)
140
+ CIO_LABEL_GETTER(material_package_uid, materialPackageUID, 32)
141
+ CIO_INT_GETTER(num_video_tracks, numVideoTracks)
142
+ CIO_INT_GETTER(num_audio_tracks, numAudioTracks)
143
+ CIO_STRING_GETTER(tracks_string, tracksString)
144
+ CIO_UINT_GETTER(track_number, trackNumber)
145
+ CIO_RATIONAL_GETTER(edit_rate, editRate)
146
+ CIO_INT64_GETTER(track_duration, trackDuration)
147
+ CIO_INT64_GETTER(segment_duration, segmentDuration)
148
+ CIO_INT64_GETTER(segment_offset, segmentOffset)
149
+ CIO_INT64_GETTER(start_timecode, startTimecode)
150
+ CIO_LABEL_GETTER(essence_container_label, essenceContainerLabel, 16)
151
+ CIO_LABEL_GETTER(file_source_package_uid, fileSourcePackageUID, 32)
152
+ CIO_LABEL_GETTER(picture_coding_label, pictureCodingLabel, 16)
153
+ CIO_UINT_GETTER(frame_layout, frameLayout)
154
+ CIO_UINT_GETTER(stored_width, storedWidth)
155
+ CIO_UINT_GETTER(stored_height, storedHeight)
156
+ CIO_UINT_GETTER(display_width, displayWidth)
157
+ CIO_UINT_GETTER(display_height, displayHeight)
158
+ CIO_RATIONAL_GETTER(audio_sampling_rate, audioSamplingRate)
159
+ CIO_UINT_GETTER(channel_count, channelCount)
160
+ CIO_UINT_GETTER(quantization_bits, quantizationBits)
161
+ CIO_STRING_GETTER(physical_package_name, physicalPackageName)
162
+ CIO_LABEL_GETTER(physical_source_package_uid, physicalSourcePackageUID, 32)
163
+ CIO_STRING_GETTER(physical_package_locator, physicalPackageLocator)
164
+ /* ... */
165
+
166
+ /* Random attributes that need special treatment. */
167
+
168
+ static
169
+ VALUE cio_get_clip_created(VALUE self)
170
+ {
171
+ AvidMXFInfo *info;
172
+ Data_Get_Struct(self, AvidMXFInfo, info);
173
+ return rb_time_from_mxf_timestamp(&info->clipCreated);
174
+ }
175
+
176
+ /*
177
+ * Left that in for reference (array creation).
178
+ static
179
+ VALUE cio_get_material_package_uid(VALUE self)
180
+ {
181
+ AvidMXFInfo *info;
182
+ Data_Get_Struct(self, AvidMXFInfo, info);
183
+
184
+ unsigned char *uid = (unsigned char*) &info->materialPackageUID;
185
+
186
+ VALUE ary = rb_ary_new2(32);
187
+ for(unsigned int i = 0; i < 32; i++)
188
+ {
189
+ rb_ary_store(ary, i, CHR2FIX(uid[i]));
190
+ }
191
+
192
+ return ary;
193
+ }
194
+ */
195
+
196
+ static
197
+ VALUE cio_get_is_video(VALUE self)
198
+ {
199
+ AvidMXFInfo *info;
200
+ Data_Get_Struct(self, AvidMXFInfo, info);
201
+ return info->isVideo ? Qtrue : Qfalse;
202
+ }
203
+
204
+ static
205
+ VALUE cio_get_essence_type(VALUE self)
206
+ {
207
+ AvidMXFInfo *info;
208
+ Data_Get_Struct(self, AvidMXFInfo, info);
209
+ return rb_str_new2(get_essence_type_string(info->essenceType, info->projectEditRate));
210
+ }
211
+
212
+ static
213
+ VALUE cio_get_aspect_ratio(VALUE self)
214
+ {
215
+ AvidMXFInfo *info;
216
+ Data_Get_Struct(self, AvidMXFInfo, info);
217
+ if(info->isVideo && info->aspectRatio.denominator != 0)
218
+ {
219
+ return rb_rational_new(INT2FIX(info->aspectRatio.numerator),
220
+ INT2FIX(info->aspectRatio.denominator));
221
+ }
222
+ else
223
+ {
224
+ return Qnil;
225
+ }
226
+ }
227
+
228
+ static
229
+ VALUE cio_get_physical_package_type(VALUE self)
230
+ {
231
+ AvidMXFInfo *info;
232
+ Data_Get_Struct(self, AvidMXFInfo, info);
233
+
234
+ VALUE ret = Qnil;
235
+ switch (info->physicalPackageType)
236
+ {
237
+ case TAPE_PHYS_TYPE:
238
+ ret = ID2SYM(rb_intern("tape"));
239
+ break;
240
+ case IMPORT_PHYS_TYPE:
241
+ ret = ID2SYM(rb_intern("import"));
242
+ break;
243
+ case RECORDING_PHYS_TYPE:
244
+ ret = ID2SYM(rb_intern("recording"));
245
+ break;
246
+ case UNKNOWN_PHYS_TYPE:
247
+ default:
248
+ ret = ID2SYM(rb_intern("unknown"));
249
+ break;
250
+ }
251
+
252
+ return ret;
253
+ }
254
+
255
+ static
256
+ VALUE cio_get_clip_track_string(VALUE self)
257
+ {
258
+ AvidMXFInfo *info;
259
+ Data_Get_Struct(self, AvidMXFInfo, info);
260
+
261
+ return rb_str_new2((info->tracksString == NULL) ? "" : info->tracksString);
262
+ }
263
+
264
+ /* Module init. */
265
+
266
+ void Init_mxfinfo()
267
+ {
268
+ m_mxfinfo = rb_define_module("MXFInfo");
269
+
270
+ c_infoobject = rb_define_class_under(m_mxfinfo, "InfoObject", rb_cObject);
271
+ rb_define_singleton_method(c_infoobject, "new", cio_new, 1);
272
+
273
+ rb_define_method(c_infoobject, "clip_name", cio_get_clip_name, 0);
274
+ rb_define_method(c_infoobject, "project_name", cio_get_project_name, 0);
275
+ rb_define_method(c_infoobject, "clip_created", cio_get_clip_created, 0);
276
+ rb_define_method(c_infoobject, "project_edit_rate", cio_get_project_edit_rate, 0);
277
+ rb_define_method(c_infoobject, "clip_duration", cio_get_clip_duration, 0);
278
+ rb_define_method(c_infoobject, "material_package_uid", cio_get_material_package_uid, 0);
279
+
280
+ /* AvidTaggedValue *userComments */
281
+ /* int numUserComments */
282
+ /* AvidTaggedValue *materialPackageAttributes */
283
+ /* int numMaterialPackageAttributes */
284
+
285
+ rb_define_method(c_infoobject, "num_video_tracks", cio_get_num_video_tracks, 0);
286
+ rb_define_method(c_infoobject, "num_audio_tracks", cio_get_num_audio_tracks, 0);
287
+ rb_define_method(c_infoobject, "tracks_string", cio_get_tracks_string, 0);
288
+ rb_define_method(c_infoobject, "track_number", cio_get_track_number, 0);
289
+ rb_define_method(c_infoobject, "is_video", cio_get_is_video, 0);
290
+ rb_define_method(c_infoobject, "edit_rate", cio_get_edit_rate, 0);
291
+ rb_define_method(c_infoobject, "track_duration", cio_get_track_duration, 0);
292
+ rb_define_method(c_infoobject, "segment_duration", cio_get_segment_duration, 0);
293
+ rb_define_method(c_infoobject, "segment_offset", cio_get_segment_offset, 0);
294
+ rb_define_method(c_infoobject, "start_timecode", cio_get_start_timecode, 0);
295
+ rb_define_method(c_infoobject, "essence_type", cio_get_essence_type, 0);
296
+ rb_define_method(c_infoobject, "essence_container_label", cio_get_essence_container_label, 0);
297
+ rb_define_method(c_infoobject, "file_source_package_uid", cio_get_file_source_package_uid, 0);
298
+ rb_define_method(c_infoobject, "picture_coding_label", cio_get_picture_coding_label, 0);
299
+ rb_define_method(c_infoobject, "frame_layout", cio_get_frame_layout, 0);
300
+ rb_define_method(c_infoobject, "aspect_ratio", cio_get_aspect_ratio, 0);
301
+ rb_define_method(c_infoobject, "stored_width", cio_get_stored_width, 0);
302
+ rb_define_method(c_infoobject, "stored_height", cio_get_stored_height, 0);
303
+ rb_define_method(c_infoobject, "display_width", cio_get_display_width, 0);
304
+ rb_define_method(c_infoobject, "display_height", cio_get_display_height, 0);
305
+ rb_define_method(c_infoobject, "audio_sampling_rate", cio_get_audio_sampling_rate, 0);
306
+ rb_define_method(c_infoobject, "channel_count", cio_get_channel_count, 0);
307
+ rb_define_method(c_infoobject, "quantization_bits", cio_get_quantization_bits, 0);
308
+ rb_define_method(c_infoobject, "physical_package_name", cio_get_physical_package_name, 0);
309
+ rb_define_method(c_infoobject, "physical_source_package_uid", cio_get_physical_source_package_uid, 0);
310
+ rb_define_method(c_infoobject, "physical_package_type", cio_get_physical_package_type, 0);
311
+ rb_define_method(c_infoobject, "physical_package_locator", cio_get_physical_package_locator, 0);
312
+ rb_define_method(c_infoobject, "clip_track_string", cio_get_clip_track_string, 0);
313
+ }
@@ -1,3 +1,3 @@
1
- class MXFinfo
2
- VERSION = "0.0.3.6"
1
+ module MXFInfo
2
+ VERSION = '0.0.4'
3
3
  end
data/lib/mxfinfo.rb CHANGED
@@ -1,130 +1,37 @@
1
- require "forwardable"
2
- require File.join(File.dirname(__FILE__),"mxfinfo/version")
3
- require File.join(File.dirname(__FILE__),"mxfinfo/attr_readers")
4
- require File.join(File.dirname(__FILE__),"mxfinfo/string")
5
-
6
- class MXFinfo
7
- extend Forwardable
8
- # We assume it's in the path of the user
9
- @@binary = 'avidmxfinfo'
10
-
11
- # BINARY CHANGE
12
- def self.binary; @@binary; end
13
- def self.binary=(binary); @@binary = binary; end
1
+ require 'mxfinfo.so'
2
+ require 'mxfinfo/version.rb'
14
3
 
4
+ module MXFInfo
15
5
  def self.scan(path)
16
- info = InfoObject.new(path)
17
- end
18
-
19
- def self.import(data)
20
- InfoObject.new(data, false)
6
+ InfoObject.new path
21
7
  end
22
8
 
23
9
  class InfoObject
24
- extend AttrReaders
25
-
26
- @@render = ["Center Smooth",
27
- "Color Correction",
28
- "Crystal",
29
- "Flip-Flop",
30
- "FluidBlur",
31
- "Left Box",
32
- "Luma Key",
33
- "Mosaic Effect",
34
- "Stabilize",
35
- "Timecode Burn-In"]
36
-
37
- # RAW AVIDMXFINFO OUTPUT
38
- def raw_data; @mxfinfo; end
39
-
40
- # Attributes
41
- def self.supported_attributes; @supported_attributes ||= []; end
42
-
43
- def initialize(input, process = true)
44
- if process
45
- @filepath = File.absolute_path(input)
46
- File.exists?(@filepath) ? @valid = true : @valid = false
47
- @mxfinfo = mxfinfo if @valid
48
- else
49
- @valid = true
50
- @mxfinfo = input
51
- end
52
- # Check if output contains error from binary
53
- @mxfinfo.include?("ERROR") ? @valid = false : @valid = true
54
- @mxfinfo.include?("Failed to open file") ? @valid = false : @valid = true
55
- @mxfinfo.include?("mxf_disk_file_open_read") ? @valid = false : @valid = true
56
- process_data if @valid
57
- end
58
-
59
- def valid?
60
- @valid
61
- end
62
-
63
- mxfinfo_attr_reader :filename
64
- mxfinfo_attr_reader :project_name
65
- mxfinfo_attr_reader :clip_name
66
- mxfinfo_date_reader :clip_created_at, "Clip Created"
67
- mxfinfo_attr_reader :project_edit_rate
68
- mxfinfo_attr_reader :clip_edit_rate
69
- mxfinfo_duration_reader :clip_duration
70
-
71
- mxfinfo_attr_reader :videotracks, "Clip Video Tracks"
72
- def v_tracks; videotracks.to_i; end
73
- alias_method :video_tracks, :v_tracks
74
-
75
- mxfinfo_attr_reader :audiotracks, "Clip Audio Tracks"
76
- def a_tracks; audiotracks.to_i; end
77
- alias_method :audio_tracks, :a_tracks
78
-
79
- mxfinfo_attr_reader :clip_track_string
80
- mxfinfo_attr_reader :essence_type
81
- mxfinfo_attr_reader :essence_label
82
-
83
- mxfinfo_attr_reader :tracknumber, "Track Number"
84
- def t_number; tracknumber.to_i; end
85
- alias_method :track_number, :t_number
86
-
87
- mxfinfo_attr_reader :edit_rate
88
- mxfinfo_duration_reader :track_duration
89
- mxfinfo_duration_reader :track_segment_duration
90
- mxfinfo_duration_reader :track_segment_offset
91
- mxfinfo_timecode_reader :start_timecode
92
- mxfinfo_attr_reader :audio_sampling_rate
93
-
94
- mxfinfo_attr_reader :channelcount, "Channel Count"
95
- def c_count; channelcount.to_i; end
96
- alias_method :channel_count, :c_count
97
-
98
- mxfinfo_attr_reader :quantizationbits, "Quantization Bits"
99
- def q_bits; quantizationbits.to_i; end
100
- alias_method :quantization_bits, :q_bits
101
-
102
- mxfinfo_attr_reader :unc_path
103
- mxfinfo_attr_reader :material_package_uid
104
- mxfinfo_attr_reader :file_package_uid
105
- mxfinfo_attr_reader :physical_package_uid
106
- mxfinfo_attr_reader :physical_package_type
107
- mxfinfo_attr_reader :physical_package_name
108
- mxfinfo_attr_reader :physical_package_locator
10
+ alias_method :videotracks, :num_video_tracks
11
+ alias_method :v_tracks, :num_video_tracks
12
+ alias_method :video_tracks, :num_video_tracks
13
+ alias_method :audiotracks, :num_audio_tracks
14
+ alias_method :audio_tracks, :num_audio_tracks
15
+ alias_method :a_tracks, :num_audio_tracks
16
+ alias_method :clip_created_at, :clip_created
17
+ alias_method :essence_label, :essence_container_label
18
+ alias_method :t_number, :track_number
19
+ alias_method :tracknumber, :track_number
20
+ alias_method :channelcount, :channel_count
21
+ alias_method :c_count, :channel_count
22
+ alias_method :file_package_uid, :file_source_package_uid
109
23
 
110
24
  def render_file?
111
25
  physical_package_name == "Precompute Source Mob"
112
26
  end
113
27
 
114
- private
115
- def mxfinfo
116
- # TODO: - add check if return data is valid
117
- `#{MXFinfo.binary} \"#{@filepath}\" 2>&1`
118
- end
119
-
120
- def process_data
121
- @processed_data = Hash.new
122
- @mxfinfo.each_line do |line|
123
- if line.include?("=")
124
- key, value = line.split("=")[0], line.split("=")[1]
125
- @processed_data[key.strip.gsub(/\s+/, "_").downcase] = value.strip
126
- end
127
- end
28
+ alias_method :essence_type_orig, :essence_type
29
+ def essence_type
30
+ result = self.send(:essence_type_orig)
31
+ if result.start_with?("DNxHD")
32
+ result.gsub!(/ \(\d+\)/, "")
128
33
  end
34
+ result
35
+ end
129
36
  end
130
37
  end