markus / ConvertService / ConverterService / ImageFields / MP4File.cs @ 3035602a
이력 | 보기 | 이력해설 | 다운로드 (4.49 KB)
1 |
using System; |
---|---|
2 |
using System.Collections.Generic; |
3 |
using System.Linq; |
4 |
using System.Text; |
5 |
using System.Runtime.InteropServices; |
6 |
using System.Diagnostics; |
7 |
using System.Net; |
8 |
using System.IO; |
9 |
|
10 |
namespace ImageFields |
11 |
{ |
12 |
internal class MP4File : IDisposable |
13 |
{ |
14 |
// Fields |
15 |
private BinaryWriter binaryWriter; |
16 |
private FileStream fileStream; |
17 |
private List<OffsetTime> offsetTimes; |
18 |
|
19 |
// Methods |
20 |
public MP4File(string fileName) |
21 |
{ |
22 |
this.fileStream = new FileStream(fileName, FileMode.Create); |
23 |
this.binaryWriter = new BinaryWriter(this.fileStream); |
24 |
this.offsetTimes = new List<OffsetTime>(); |
25 |
this.WriteInt32(0x18); |
26 |
this.WriteFourCC("ftyp"); |
27 |
this.WriteFourCC("iso2"); |
28 |
this.WriteInt32(0); |
29 |
this.WriteFourCC("isom"); |
30 |
this.WriteFourCC("msas"); |
31 |
this.WriteInt32(8); |
32 |
this.WriteFourCC("moov"); |
33 |
} |
34 |
|
35 |
public void Close() |
36 |
{ |
37 |
this.Dispose(); |
38 |
} |
39 |
|
40 |
public void Dispose() |
41 |
{ |
42 |
if (this.fileStream != null) |
43 |
{ |
44 |
this.WriteInt32(0x30 + (0x13 * this.offsetTimes.Count)); |
45 |
this.WriteFourCC("mfra"); |
46 |
this.WriteInt32(0x18 + (0x13 * this.offsetTimes.Count)); |
47 |
this.WriteFourCC("tfra"); |
48 |
this.binaryWriter.Write((byte)1); |
49 |
this.binaryWriter.Write((byte)0); |
50 |
this.binaryWriter.Write((byte)0); |
51 |
this.binaryWriter.Write((byte)0); |
52 |
this.WriteInt32(1); |
53 |
this.WriteInt32(0); |
54 |
this.WriteInt32(this.offsetTimes.Count); |
55 |
for (int i = 0; i < this.offsetTimes.Count; i++) |
56 |
{ |
57 |
this.WriteInt64(this.offsetTimes[i].Time); |
58 |
this.WriteInt64(this.offsetTimes[i].Offset); |
59 |
this.binaryWriter.Write((byte)1); |
60 |
this.binaryWriter.Write((byte)1); |
61 |
this.binaryWriter.Write((byte)1); |
62 |
} |
63 |
this.WriteInt32(0x10); |
64 |
this.WriteFourCC("mfro"); |
65 |
this.WriteInt32(0); |
66 |
this.WriteInt32(0x30 + (0x13 * this.offsetTimes.Count)); |
67 |
this.binaryWriter.Close(); |
68 |
this.fileStream.Close(); |
69 |
this.offsetTimes = null; |
70 |
this.binaryWriter = null; |
71 |
this.fileStream = null; |
72 |
GC.SuppressFinalize(this); |
73 |
} |
74 |
} |
75 |
|
76 |
~MP4File() |
77 |
{ |
78 |
this.Dispose(); |
79 |
} |
80 |
|
81 |
private void WriteFourCC(string s) |
82 |
{ |
83 |
this.binaryWriter.Write(s[0]); |
84 |
this.binaryWriter.Write(s[1]); |
85 |
this.binaryWriter.Write(s[2]); |
86 |
this.binaryWriter.Write(s[3]); |
87 |
} |
88 |
|
89 |
private void WriteInt32(int i) |
90 |
{ |
91 |
this.binaryWriter.Write(IPAddress.HostToNetworkOrder(i)); |
92 |
} |
93 |
|
94 |
private void WriteInt64(long i) |
95 |
{ |
96 |
this.binaryWriter.Write(IPAddress.HostToNetworkOrder(i)); |
97 |
} |
98 |
|
99 |
public void WriteMP4Fragment(byte[] bytes, long time) |
100 |
{ |
101 |
if (this.offsetTimes.Count > 0) |
102 |
{ |
103 |
Debug.Assert(this.offsetTimes[this.offsetTimes.Count - 1].Time < time, "Times are out of order in MP4 file, will not work with IIS Smooth Streaming"); |
104 |
} |
105 |
OffsetTime item = new OffsetTime |
106 |
{ |
107 |
Offset = this.binaryWriter.BaseStream.Position, |
108 |
Time = time |
109 |
}; |
110 |
this.offsetTimes.Add(item); |
111 |
this.WriteInt32(0x40); |
112 |
this.WriteFourCC("moof"); |
113 |
this.WriteInt32(0x10); |
114 |
this.WriteFourCC("mfhd"); |
115 |
this.WriteInt32(0); |
116 |
this.WriteInt32(this.offsetTimes.Count); |
117 |
this.WriteInt32(40); |
118 |
this.WriteFourCC("traf"); |
119 |
this.WriteInt32(0x10); |
120 |
this.WriteFourCC("tfhd"); |
121 |
this.WriteInt32(0); |
122 |
this.WriteInt32(1); |
123 |
this.WriteInt32(0x10); |
124 |
this.WriteFourCC("trun"); |
125 |
this.WriteInt32(0); |
126 |
this.WriteInt32(1); |
127 |
this.WriteInt32(8 + bytes.Length); |
128 |
this.WriteFourCC("mdat"); |
129 |
this.binaryWriter.Write(bytes); |
130 |
this.binaryWriter.Flush(); |
131 |
} |
132 |
|
133 |
// Nested Types |
134 |
[StructLayout(LayoutKind.Sequential)] |
135 |
internal struct OffsetTime |
136 |
{ |
137 |
public long Offset; |
138 |
public long Time; |
139 |
} |
140 |
} |
141 |
|
142 |
|
143 |
|
144 |
} |