You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
19 KiB

  1. using JT1078.FMp4.MessagePack;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using Xunit;
  6. using JT1078.Protocol.Extensions;
  7. using JT1078.FMp4.Enums;
  8. using JT1078.FMp4.Samples;
  9. using System.Buffers.Binary;
  10. using System.IO;
  11. using System.Linq;
  12. namespace JT1078.FMp4.Test
  13. {
  14. public class FMp4Box_Test
  15. {
  16. /// <summary>
  17. /// 使用doc/video/fragmented_demo.mp4
  18. /// </summary>
  19. [Fact(DisplayName = "ftyp")]
  20. public void ftyp_test()
  21. {
  22. var MinorVersion = Encoding.ASCII.GetString(new byte[4] { 0,0,2,0});
  23. FileTypeBox fileTypeBox = new FileTypeBox();
  24. fileTypeBox.MajorBrand = "isom";
  25. fileTypeBox.MinorVersion = "\0\0\u0002\0";
  26. fileTypeBox.CompatibleBrands.Add("isom");
  27. fileTypeBox.CompatibleBrands.Add("iso2");
  28. fileTypeBox.CompatibleBrands.Add("avc1");
  29. fileTypeBox.CompatibleBrands.Add("iso6");
  30. fileTypeBox.CompatibleBrands.Add("mp41");
  31. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x25]);
  32. fileTypeBox.ToBuffer(ref writer);
  33. var hex = writer.FlushAndGetArray().ToHexString();
  34. Assert.Equal("000000246674797069736f6d0000020069736f6d69736f326176633169736f366d703431".ToUpper(), hex);
  35. }
  36. /// <summary>
  37. /// 使用doc/video/fragmented_demo.mp4
  38. /// </summary>
  39. [Fact(DisplayName = "moov_mvhd")]
  40. public void moov_mvhd_test()
  41. {
  42. MovieHeaderBox movieHeaderBox = new MovieHeaderBox(0);
  43. movieHeaderBox.CreationTime = 0;
  44. movieHeaderBox.ModificationTime = 0;
  45. movieHeaderBox.Timescale = 1000;
  46. movieHeaderBox.Duration = 0;
  47. movieHeaderBox.NextTrackID = 2;
  48. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
  49. movieHeaderBox.ToBuffer(ref writer);
  50. var hex = writer.FlushAndGetArray().ToHexString();
  51. Assert.Equal("0000006c6d766864000000000000000000000000000003e8000000000001000001000000000000000000000000010000000000000000000000000000000100000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002".ToUpper(), hex);
  52. }
  53. /// <summary>
  54. /// 使用doc/video/fragmented_demo.mp4
  55. /// </summary>
  56. [Fact(DisplayName = "moov_trak_tkhd")]
  57. public void moov_trak_tkhd_test()
  58. {
  59. TrackHeaderBox trackHeaderBox = new TrackHeaderBox(0,3);
  60. trackHeaderBox.CreationTime = 0;
  61. trackHeaderBox.ModificationTime = 0;
  62. trackHeaderBox.TrackID = 1;
  63. trackHeaderBox.Duration = 0;
  64. trackHeaderBox.Width = 544u;
  65. trackHeaderBox.Height = 960u;
  66. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
  67. trackHeaderBox.ToBuffer(ref writer);
  68. var hex = writer.FlushAndGetArray().ToHexString();
  69. Assert.Equal("0000005C746B68640000000300000000000000000000000100000000000000000000000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000004000000000000220000003C0".ToUpper(), hex);
  70. }
  71. /// <summary>
  72. /// 使用doc/video/fragmented_demo.mp4
  73. /// </summary>
  74. [Fact(DisplayName = "moov_trak_mdia")]
  75. public void moov_trak_mdia_test()
  76. {
  77. }
  78. /// <summary>
  79. /// 使用doc/video/fragmented_demo.mp4
  80. /// </summary>
  81. [Fact(DisplayName = "moov_trak_mdia_mdhd")]
  82. public void moov_trak_mdia_mdhd_test()
  83. {
  84. MediaHeaderBox mediaHeaderBox = new MediaHeaderBox(0, 0);
  85. mediaHeaderBox.CreationTime = 0;
  86. mediaHeaderBox.ModificationTime = 0;
  87. mediaHeaderBox.Timescale = 0x00124f80;
  88. mediaHeaderBox.Duration = 0;
  89. mediaHeaderBox.Language = "und";
  90. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
  91. mediaHeaderBox.ToBuffer(ref writer);
  92. var hex = writer.FlushAndGetArray().ToHexString();
  93. //000000206d64686400000000000000000000000000124f800000000055c40000
  94. //00000020
  95. //6d646864
  96. //00000000
  97. //00000000
  98. //00000000
  99. //00124f80
  100. //00000000
  101. //55c4
  102. //0000
  103. Assert.Equal("000000206d64686400000000000000000000000000124f800000000055c40000".ToUpper(), hex);
  104. }
  105. /// <summary>
  106. /// 使用doc/video/fragmented_demo.mp4
  107. /// </summary>
  108. [Fact(DisplayName = "moov_trak_mdia_hdlr")]
  109. public void moov_trak_mdia_hdlr_test()
  110. {
  111. HandlerBox handlerBox = new HandlerBox(0, 0);
  112. handlerBox.HandlerType = Enums.HandlerType.vide;
  113. handlerBox.Name = "VideoHandler";
  114. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
  115. handlerBox.ToBuffer(ref writer);
  116. var hex = writer.FlushAndGetArray().ToHexString();
  117. Assert.Equal("0000002C68646C72000000000000000076696465000000000000000000000000566964656F48616E646C6572".ToUpper(), hex);
  118. }
  119. /// <summary>
  120. /// 使用doc/video/fragmented_demo.mp4
  121. /// </summary>
  122. [Fact(DisplayName = "moov_trak_mdia_hdlr_minf")]
  123. public void moov_trak_mdia_hdlr_minf_test()
  124. {
  125. HandlerBox handlerBox = new HandlerBox(0, 0);
  126. handlerBox.HandlerType = Enums.HandlerType.vide;
  127. handlerBox.Name = "VideoHandler\0";
  128. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
  129. handlerBox.ToBuffer(ref writer);
  130. var hex = writer.FlushAndGetArray().ToHexString();
  131. Assert.Equal("0000002D68646C72000000000000000076696465000000000000000000000000566964656F48616E646C657200".ToUpper(), hex);
  132. }
  133. /// <summary>
  134. /// 使用doc/video/fragmented_demo.mp4
  135. /// </summary>
  136. [Fact(DisplayName = "moov_trak_mdia_hdlr_minf_vmhd")]
  137. public void moov_trak_mdia_hdlr_minf_vmhd_test()
  138. {
  139. VideoMediaHeaderBox videoMediaHeaderBox = new VideoMediaHeaderBox();
  140. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
  141. videoMediaHeaderBox.ToBuffer(ref writer);
  142. var hex = writer.FlushAndGetArray().ToHexString();
  143. Assert.Equal("00000014766d6864000000010000000000000000".ToUpper(), hex);
  144. }
  145. /// <summary>
  146. /// 使用doc/video/fragmented_demo.mp4
  147. /// </summary>
  148. [Fact(DisplayName = "moov_trak_mdia_hdlr_minf_dinf")]
  149. public void moov_trak_mdia_hdlr_minf_dinf_test()
  150. {
  151. DataInformationBox dataInformationBox = new DataInformationBox();
  152. DataReferenceBox dataReferenceBox = new DataReferenceBox();
  153. dataReferenceBox.DataEntryBoxes = new List<DataEntryBox>();
  154. dataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(version: 0, flags: 1));
  155. dataInformationBox.DataReferenceBox = dataReferenceBox;
  156. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[10240]);
  157. dataInformationBox.ToBuffer(ref writer);
  158. var hex = writer.FlushAndGetArray().ToHexString();
  159. //0000002464696e660000001c6472656600000000000000010000000c75726c2000000001
  160. Assert.Equal("0000002464696e660000001c6472656600000000000000010000000c75726c2000000001".ToUpper(), hex);
  161. }
  162. /// <summary>
  163. /// 使用doc/video/fragmented_demo.mp4
  164. /// </summary>
  165. [Fact(DisplayName = "moov_trak_mdia_hdlr_minf_stbl")]
  166. public void moov_trak_mdia_hdlr_minf_stbl_test()
  167. {
  168. //000000e17374626c000000957374736400000000000000010000008561766331000000000000000100000000000000000000000000000000022003c0004800000048000000000000000100000000000000000000000000000000000000000000000000000000000000000018ffff0000002f617663430164001fffe100176764001facd940881e684000f4240037b40883c60c658001000568efbcb0000000001073747473000000000000000000000010737473630000000000000000000000147374737a000000000000000000000000000000107374636f0000000000000000
  169. //stbl
  170. SampleTableBox sampleTableBox = new SampleTableBox();
  171. //stbl->stsd
  172. SampleDescriptionBox sampleDescriptionBox = new SampleDescriptionBox(HandlerType.none);
  173. //stbl->stsd->avc1
  174. AVC1SampleEntry aVC1SampleEntry = new AVC1SampleEntry();
  175. aVC1SampleEntry.Width = 0x0220;
  176. aVC1SampleEntry.Height = 0x03c0;
  177. //stbl->stsd->avc1->avcc
  178. AVCConfigurationBox aVCConfigurationBox = new AVCConfigurationBox();
  179. aVCConfigurationBox.AVCProfileIndication = 0x64;
  180. aVCConfigurationBox.ProfileCompatibility = 0;
  181. aVCConfigurationBox.AVCLevelIndication = 0x1f;
  182. aVCConfigurationBox.LengthSizeMinusOne = 0xff;
  183. aVCConfigurationBox.SPSs = new List<byte[]>()
  184. {
  185. "6764001facd940881e684000f4240037b40883c60c6580".ToHexBytes()
  186. };
  187. aVCConfigurationBox.PPSs = new List<byte[]>()
  188. {
  189. "68efbcb000".ToHexBytes()
  190. };
  191. aVC1SampleEntry.AVCConfigurationBox = aVCConfigurationBox;
  192. sampleDescriptionBox.SampleEntries = new List<SampleEntry>()
  193. {
  194. aVC1SampleEntry
  195. };
  196. sampleTableBox.SampleDescriptionBox = sampleDescriptionBox;
  197. //stbl->stts
  198. sampleTableBox.TimeToSampleBox = new TimeToSampleBox();
  199. //stbl->stsc
  200. sampleTableBox.SampleToChunkBox = new SampleToChunkBox();
  201. //stbl->stsz
  202. sampleTableBox.SampleSizeBox = new SampleSizeBox();
  203. //stbl->stco
  204. sampleTableBox.ChunkOffsetBox = new ChunkOffsetBox();
  205. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x000000e1]);
  206. sampleTableBox.ToBuffer(ref writer);
  207. var hex = writer.FlushAndGetArray().ToHexString();
  208. Assert.Equal("000000e17374626c000000957374736400000000000000010000008561766331000000000000000100000000000000000000000000000000022003c0004800000048000000000000000100000000000000000000000000000000000000000000000000000000000000000018ffff0000002f617663430164001fffe100176764001facd940881e684000f4240037b40883c60c658001000568efbcb0000000001073747473000000000000000000000010737473630000000000000000000000147374737a000000000000000000000000000000107374636f0000000000000000".ToUpper(), hex);
  209. }
  210. /// <summary>
  211. /// 使用doc/video/fragmented_demo.mp4
  212. /// </summary>
  213. [Fact(DisplayName = "moov_mvex")]
  214. public void trak_mvex_test()
  215. {
  216. //moov->mvex
  217. MovieExtendsBox movieExtendsBox = new MovieExtendsBox();
  218. //moov->mvex->trex
  219. movieExtendsBox.TrackExtendsBoxs = new List<TrackExtendsBox>();
  220. TrackExtendsBox trackExtendsBox1 = new TrackExtendsBox();
  221. trackExtendsBox1.TrackID = 0x01;
  222. trackExtendsBox1.DefaultSampleDescriptionIndex = 0x01;
  223. movieExtendsBox.TrackExtendsBoxs.Add(trackExtendsBox1);
  224. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x00000028]);
  225. movieExtendsBox.ToBuffer(ref writer);
  226. var hex = writer.FlushAndGetArray().ToHexString();
  227. Assert.Equal("000000286d7665780000002074726578000000000000000100000001000000000000000000000000".ToUpper(), hex);
  228. }
  229. /// <summary>
  230. /// 使用doc/video/fragmented_demo.mp4
  231. /// </summary>
  232. [Fact(DisplayName = "moov_udta")]
  233. public void moov_udta_test()
  234. {
  235. //todo:moov->udta
  236. }
  237. /// <summary>
  238. /// 使用doc/video/fragmented_demo.mp4
  239. /// </summary>
  240. [Fact(DisplayName = "moof")]
  241. public void moof_test()
  242. {
  243. //000006d8747261660000002474666864000000390000000100000000000002fc0000bb80000066ee01010000
  244. //00 00 06 d8
  245. //74 72 61 66
  246. //00 00 00 24
  247. //74 66 68 64
  248. //00
  249. //00 00 39
  250. //00 00 00 01
  251. //00 00 00 00 00 00 02 fc
  252. //00 00 bb 80
  253. //00 00 66 ee
  254. //01 01 00 00
  255. //moof
  256. MovieFragmentBox movieFragmentBox = new MovieFragmentBox();
  257. //moof->mfhd
  258. movieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox();
  259. movieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = 0x01;
  260. //moof->traf
  261. movieFragmentBox.TrackFragmentBox = new TrackFragmentBox();
  262. //moof->traf->tfhd
  263. movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x000039);
  264. movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 0x01;
  265. movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset = 0x00000000000002fc;
  266. movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 0x0000bb80;
  267. movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = 0x000066ee;
  268. movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x01010000;
  269. //moof->tfdt
  270. movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox();
  271. //moof->trun
  272. //000006987472756E00000305000000D0000006F802000000
  273. //00 00 06 98
  274. //74 72 75 6E
  275. //00
  276. //00 03 05
  277. //00 00 00 D0 SampleCount
  278. //00 00 06 F8 DataOffset
  279. //02 00 00 00 FirstSampleFlags
  280. //fragmented_demo_trun.txt TrackRunInfos
  281. movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(0, 0x00000305);
  282. movieFragmentBox.TrackFragmentBox.TrackRunBox.SampleCount = 0x000000D0;
  283. movieFragmentBox.TrackFragmentBox.TrackRunBox.DataOffset = 0x000006F8;
  284. movieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 0x02000000;
  285. movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List<TrackRunBox.TrackRunInfo>();
  286. var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FMP4", "fragmented_demo_trun.txt"));
  287. var buffers = lines.Where(w => !string.IsNullOrEmpty(w)).Select(s => s.ToHexBytes()).ToList();
  288. //SampleDuration
  289. //SampleSize
  290. foreach (var buffer in buffers)
  291. {
  292. var mod = buffer.Length / 8;
  293. for (int i = 0; i < mod; i++)
  294. {
  295. TrackRunBox.TrackRunInfo trackRunInfo = new TrackRunBox.TrackRunInfo();
  296. trackRunInfo.SampleDuration = BinaryPrimitives.ReadUInt32BigEndian(buffer.Skip(i * 4).Take(4).ToArray());
  297. trackRunInfo.SampleSize= BinaryPrimitives.ReadUInt32BigEndian(buffer.Skip((i + 1)*4).Take(4).ToArray());
  298. movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(trackRunInfo);
  299. }
  300. }
  301. Assert.Equal(0x00000698, movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Count*8+4*6);
  302. }
  303. /// <summary>
  304. /// 使用doc/video/fragmented_demo.mp4
  305. /// </summary>
  306. [Fact(DisplayName = "mdat")]
  307. public void mdat_test()
  308. {
  309. MediaDataBox mediaDataBox = new MediaDataBox();
  310. var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FMP4", "fragmented_demo_mdat.txt"));
  311. var buffers = lines.Where(w => !string.IsNullOrEmpty(w)).Select(s => s.ToHexBytes()).ToList();
  312. List<byte> data = new List<byte>();
  313. foreach (var buffer in buffers)
  314. {
  315. data = data.Concat(buffer).ToList();
  316. }
  317. //00 0E 3C 9C Size
  318. //6D 64 61 74 BoxType
  319. Assert.Equal(0x000E3C9C-8, data.Count);
  320. }
  321. /// <summary>
  322. /// 使用doc/video/fragmented_demo.mp4
  323. /// </summary>
  324. [Fact(DisplayName = "mfra")]
  325. public void mfra_test()
  326. {
  327. //000000436d6672610000002b7466726101000000000000010000000000000001000000000000000000000000000002fc010101000000106d66726f0000000000000043
  328. //00 00 00 43
  329. //6d 66 72 61
  330. //00 00 00 2b
  331. //74 66 72 61
  332. //01
  333. //00 00 00
  334. //00 00 00 01
  335. //00 00 00 00
  336. //00 00 00 01
  337. //00 00 00 00 00 00 00 00
  338. //00 00 00 00 00 00 02 fc
  339. //01 01 01
  340. //00 00 00 10
  341. //6d 66 72 6f
  342. //00
  343. //00 00 00
  344. //00 00 00 43
  345. //mfra
  346. MovieFragmentRandomAccessBox movieFragmentRandomAccessBox = new MovieFragmentRandomAccessBox();
  347. //mfra->tfra
  348. movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox = new TrackFragmentRandomAccessBox(1);
  349. movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackID = 0x01;
  350. movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos = new List<TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo>();
  351. TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo trackFragmentRandomAccessInfo1 = new TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfo();
  352. trackFragmentRandomAccessInfo1.Time = 0;
  353. trackFragmentRandomAccessInfo1.MoofOffset = 0x00000000000002fc;
  354. trackFragmentRandomAccessInfo1.TrafNumber = 0x01;
  355. trackFragmentRandomAccessInfo1.TrunNumber = 0x01;
  356. trackFragmentRandomAccessInfo1.SampleNumber = 0x01;
  357. movieFragmentRandomAccessBox.TrackFragmentRandomAccessBox.TrackFragmentRandomAccessInfos.Add(trackFragmentRandomAccessInfo1);
  358. //mfra->mfro
  359. movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox = new MovieFragmentRandomAccessOffsetBox(0);
  360. movieFragmentRandomAccessBox.MovieFragmentRandomAccessOffsetBox.MfraSize = 0x00000043;
  361. FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x00000043]);
  362. movieFragmentRandomAccessBox.ToBuffer(ref writer);
  363. var hex = writer.FlushAndGetArray().ToHexString();
  364. Assert.Equal("000000436d6672610000002b7466726101000000000000010000000000000001000000000000000000000000000002fc010101000000106d66726f0000000000000043".ToUpper(), hex);
  365. }
  366. }
  367. }