@@ -333,3 +333,4 @@ ASALocalRun/ | |||
/src/JT1078.Flv.Test/H264/JT1078_5.txt | |||
/doc/tools/FlvAnalyzer.exe | |||
/doc/tools/EasyICE_2.7.0.2 | |||
/doc/tools/mp4parse |
@@ -0,0 +1,28 @@ | |||
using JT1078.FMp4.MessagePack; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using Xunit; | |||
using JT1078.Protocol.Extensions; | |||
namespace JT1078.FMp4.Test.Boxs | |||
{ | |||
public class FileTypeBox_Test | |||
{ | |||
/// <summary> | |||
/// 使用doc/video/demo.mp4 | |||
/// </summary> | |||
[Fact] | |||
public void Test1() | |||
{ | |||
FileTypeBox fileTypeBox = new FileTypeBox(); | |||
fileTypeBox.MajorBrand = "mp42"; | |||
fileTypeBox.CompatibleBrands.Add("mp42"); | |||
fileTypeBox.CompatibleBrands.Add("isom"); | |||
FMp4MessagePackWriter writer = new MessagePack.FMp4MessagePackWriter(new byte[0x18]); | |||
fileTypeBox.ToBuffer(ref writer); | |||
var hex=writer.FlushAndGetArray().ToHexString(); | |||
Assert.Equal("00000018667479706d703432000000006d70343269736f6d".ToUpper(), hex); | |||
} | |||
} | |||
} |
@@ -1,14 +0,0 @@ | |||
using System; | |||
using Xunit; | |||
namespace JT1078.FMp4.Test | |||
{ | |||
public class UnitTest1 | |||
{ | |||
[Fact] | |||
public void Test1() | |||
{ | |||
} | |||
} | |||
} |
@@ -1,4 +1,6 @@ | |||
using System; | |||
using JT1078.FMp4.Interfaces; | |||
using JT1078.FMp4.MessagePack; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Runtime.Serialization; | |||
using System.Text; | |||
@@ -8,7 +10,7 @@ namespace JT1078.FMp4 | |||
/// <summary> | |||
/// ftyp 盒子相当于就是该 mp4 的纲领性说明。即,告诉解码器它的基本解码版本,兼容格式。简而言之,就是用来告诉客户端,该 MP4 的使用的解码标准。通常,ftyp 都是放在 MP4 的开头。 | |||
/// </summary> | |||
public class FileTypeBox : Mp4Box | |||
public class FileTypeBox : Mp4Box, IFMp4MessagePackFormatter | |||
{ | |||
public FileTypeBox() : base("ftyp") | |||
{ | |||
@@ -22,11 +24,26 @@ namespace JT1078.FMp4 | |||
/// 最低兼容版本 | |||
/// 4位 | |||
/// </summary> | |||
public uint MinorVersion { get; set; } | |||
public string MinorVersion { get; set; } = "\0\0\0\0"; | |||
/// <summary> | |||
/// 和MajorBrand类似,通常是针对 MP4 中包含的额外格式,比如,AVC,AAC 等相当于的音视频解码格式。 | |||
/// 4位*n | |||
/// </summary> | |||
public List<string> CompatibleBrands { get; set; } | |||
public List<string> CompatibleBrands { get; set; } = new List<string>(); | |||
public void ToBuffer(ref FMp4MessagePackWriter writer) | |||
{ | |||
ToBuffer(ref writer,out int sizePosition); | |||
writer.WriteASCII(MajorBrand); | |||
writer.WriteASCII(MinorVersion); | |||
if(CompatibleBrands!=null && CompatibleBrands.Count > 0) | |||
{ | |||
foreach(var item in CompatibleBrands) | |||
{ | |||
writer.WriteASCII(item); | |||
} | |||
} | |||
writer.WriteUInt32Return((uint)(writer.GetCurrentPosition()- sizePosition), sizePosition); | |||
} | |||
} | |||
} |
@@ -11,7 +11,13 @@ namespace JT1078.FMp4 | |||
Version = version; | |||
Flags = flags; | |||
} | |||
/// <summary> | |||
/// unsigned int(8) | |||
/// </summary> | |||
public byte Version { get; set; } | |||
/// <summary> | |||
/// bit(24) | |||
/// </summary> | |||
public uint Flags { get; set; } | |||
} | |||
} |
@@ -348,6 +348,16 @@ | |||
日期限制于2000年 | |||
</summary> | |||
</member> | |||
<member name="P:JT1078.FMp4.FullBox.Version"> | |||
<summary> | |||
unsigned int(8) | |||
</summary> | |||
</member> | |||
<member name="P:JT1078.FMp4.FullBox.Flags"> | |||
<summary> | |||
bit(24) | |||
</summary> | |||
</member> | |||
<member name="M:JT1078.FMp4.MessagePack.FMp4MessagePackReader.ReadIso639"> | |||
<summary> | |||
@@ -362,6 +372,23 @@ | |||
</summary> | |||
<param name="language"></param> | |||
</member> | |||
<member name="P:JT1078.FMp4.Mp4Box.Size"> | |||
<summary> | |||
盒子大小 | |||
</summary> | |||
</member> | |||
<member name="P:JT1078.FMp4.Mp4Box.BoxType"> | |||
<summary> | |||
盒子类型 | |||
</summary> | |||
</member> | |||
<member name="M:JT1078.FMp4.Mp4Box.ToBuffer(JT1078.FMp4.MessagePack.FMp4MessagePackWriter@,System.Int32@)"> | |||
<summary> | |||
</summary> | |||
<param name="writer"></param> | |||
<param name="sizePosition"></param> | |||
</member> | |||
<!-- Badly formed XML comment ignored for member "P:JT1078.FMp4.Samples.AudioSampleEntry.Samplerate" --> | |||
</members> | |||
</doc> |
@@ -43,6 +43,14 @@ namespace JT1078.FMp4.MessagePack | |||
BinaryPrimitives.WriteUInt32BigEndian(writer.Free, value); | |||
writer.Advance(4); | |||
} | |||
public void WriteASCII(string value) | |||
{ | |||
var data = Encoding.ASCII.GetBytes(value); | |||
data.CopyTo(writer.Free); | |||
writer.Advance(data.Length); | |||
} | |||
public void WriteArray(ReadOnlySpan<byte> src) | |||
{ | |||
src.CopyTo(writer.Free); | |||
@@ -55,6 +63,24 @@ namespace JT1078.FMp4.MessagePack | |||
tmp.CopyTo(writer.Free); | |||
writer.Advance(count); | |||
} | |||
public void WriteUInt16Return(ushort value, int position) | |||
{ | |||
BinaryPrimitives.WriteUInt16BigEndian(writer.Written.Slice(position, 2), value); | |||
} | |||
public void WriteInt32Return(int value, int position) | |||
{ | |||
BinaryPrimitives.WriteInt32BigEndian(writer.Written.Slice(position, 4), value); | |||
} | |||
public void WriteUInt32Return(uint value, int position) | |||
{ | |||
BinaryPrimitives.WriteUInt32BigEndian(writer.Written.Slice(position, 4), value); | |||
} | |||
public void WriteByteReturn(byte value, int position) | |||
{ | |||
writer.Written[position] = value; | |||
} | |||
public int GetCurrentPosition() | |||
{ | |||
return writer.WrittenCount; | |||
@@ -1,4 +1,5 @@ | |||
using System; | |||
using JT1078.FMp4.MessagePack; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
@@ -6,22 +7,57 @@ namespace JT1078.FMp4 | |||
{ | |||
public abstract class Mp4Box | |||
{ | |||
public const string UUID = "uuid"; | |||
//public const string UUID = "uuid"; | |||
public const int FixedSizeLength = 4; | |||
public Mp4Box(string boxType) | |||
{ | |||
BoxType = boxType; | |||
} | |||
public Mp4Box(string boxType,string extendedType) | |||
///// <summary> | |||
///// 不考虑自定义 | |||
///// </summary> | |||
//public Mp4Box(string boxType, string extendedType) | |||
//{ | |||
// BoxType = boxType; | |||
// if (boxType == UUID) | |||
// { | |||
// UserType = extendedType; | |||
// } | |||
//} | |||
/// <summary> | |||
/// 盒子大小 | |||
/// </summary> | |||
public uint Size { get; set; } | |||
///// <summary> | |||
///// 不考虑size==1 | |||
///// size==1 | |||
///// </summary> | |||
//public ulong SizeLarge { get; set; } | |||
/// <summary> | |||
/// 盒子类型 | |||
/// </summary> | |||
public string BoxType { get; set; } | |||
///// <summary> | |||
///// 不考虑boxtype==‘uuid' | |||
///// boxtype==‘uuid’ | |||
///// int(8)[16] | |||
///// </summary> | |||
//public string UserType { get; set; } | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="writer"></param> | |||
/// <param name="sizePosition"></param> | |||
public void ToBuffer(ref FMp4MessagePackWriter writer, out int sizePosition) | |||
{ | |||
BoxType = boxType; | |||
if(boxType == UUID) | |||
{ | |||
UserType = extendedType; | |||
} | |||
writer.Skip(FixedSizeLength, out sizePosition); | |||
writer.WriteASCII(BoxType); | |||
} | |||
public string BoxType { get; set; } | |||
public string UserType { get; set; } | |||
public uint Size { get; set; } | |||
public ulong SizeLarge{get;set;} | |||
} | |||
} |