mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-10-27 22:42:38 +01:00
Working on mp4
git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@678 99eadd0c-20b8-1223-b5c4-2a2b2df33de2
This commit is contained in:
parent
9b4cc2cda8
commit
a0e3220ada
69
src/Logic/Mp4/Boxes/Box.cs
Normal file
69
src/Logic/Mp4/Boxes/Box.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Box
|
||||
{
|
||||
internal byte[] buffer;
|
||||
internal ulong pos;
|
||||
internal string name;
|
||||
internal UInt64 size;
|
||||
|
||||
public uint GetUInt(byte[] buffer, int index)
|
||||
{
|
||||
return (uint)((buffer[index] << 24) + (buffer[index + 1] << 16) + (buffer[index + 2] << 8) + buffer[index + 3]);
|
||||
}
|
||||
|
||||
public uint GetUInt(int index)
|
||||
{
|
||||
return (uint)((buffer[index] << 24) + (buffer[index + 1] << 16) + (buffer[index + 2] << 8) + buffer[index + 3]);
|
||||
}
|
||||
|
||||
public UInt64 GetUInt64(int index)
|
||||
{
|
||||
return (UInt64)((buffer[index] << 56) + (buffer[index + 1] << 48) + (buffer[index + 2] << 40) + (buffer[index + 3] << 32) +
|
||||
(buffer[index] << 24) + (buffer[index + 1] << 16) + (buffer[index + 2] << 8) + buffer[index + 3]);
|
||||
|
||||
}
|
||||
|
||||
public int GetWord(int index)
|
||||
{
|
||||
return (buffer[index] << 8) + buffer[index + 1];
|
||||
}
|
||||
|
||||
public string GetString(int index, int count)
|
||||
{
|
||||
return Encoding.UTF8.GetString(buffer, index, count);
|
||||
}
|
||||
|
||||
public string GetString(byte[] buffer, int index, int count)
|
||||
{
|
||||
return Encoding.UTF8.GetString(buffer, index, count);
|
||||
}
|
||||
|
||||
internal bool InitializeSizeAndName(System.IO.FileStream fs)
|
||||
{
|
||||
buffer = new byte[8];
|
||||
var bytesRead = fs.Read(buffer, 0, buffer.Length);
|
||||
if (bytesRead < buffer.Length)
|
||||
return false;
|
||||
size = GetUInt(0);
|
||||
name = GetString(4, 4);
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
size = (UInt64)(fs.Length - fs.Position);
|
||||
}
|
||||
if (size == 1)
|
||||
{
|
||||
bytesRead = fs.Read(buffer, 0, buffer.Length);
|
||||
if (bytesRead < buffer.Length)
|
||||
return false;
|
||||
size = GetUInt64(0);
|
||||
}
|
||||
pos = ((ulong)(fs.Position)) + size - 8;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Mdhd
|
||||
public class Mdhd : Box
|
||||
{
|
||||
|
||||
public readonly UInt64 CreationTime;
|
||||
@ -15,32 +15,32 @@ namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
|
||||
public Mdhd(FileStream fs, ulong size)
|
||||
{
|
||||
byte[] b = new byte[size - 4];
|
||||
fs.Read(b, 0, b.Length);
|
||||
buffer = new byte[size - 4];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
int languageIndex = 20;
|
||||
int version = b[0];
|
||||
int version = buffer[0];
|
||||
if (version == 0)
|
||||
{
|
||||
CreationTime = Helper.GetUInt(b, 4);
|
||||
ModificationTime = Helper.GetUInt(b, 8);
|
||||
TimeScale = Helper.GetUInt(b, 12);
|
||||
Duration = Helper.GetUInt(b, 16);
|
||||
Quality = Helper.GetWord(b, 22);
|
||||
CreationTime = GetUInt(4);
|
||||
ModificationTime = GetUInt(8);
|
||||
TimeScale = GetUInt(12);
|
||||
Duration = GetUInt(16);
|
||||
Quality = GetWord(22);
|
||||
}
|
||||
else
|
||||
{
|
||||
CreationTime = Helper.GetUInt64(b, 4);
|
||||
ModificationTime = Helper.GetUInt64(b, 12);
|
||||
TimeScale = Helper.GetUInt(b, 16);
|
||||
Duration = Helper.GetUInt64(b, 20);
|
||||
CreationTime = GetUInt64(4);
|
||||
ModificationTime = GetUInt64(12);
|
||||
TimeScale = GetUInt(16);
|
||||
Duration = GetUInt64(20);
|
||||
languageIndex = 24;
|
||||
Quality = Helper.GetWord(b, 26);
|
||||
Quality = GetWord(26);
|
||||
}
|
||||
|
||||
// language code = skip first byte, 5 bytes + 5 bytes + 5 bytes (add 0x60 to get ascii value)
|
||||
int languageByte = ((b[languageIndex] << 1) >> 3) + 0x60;
|
||||
int languageByte2 = ((b[languageIndex] & 0x3) << 3) + (b[languageIndex+1] >> 5) + 0x60;
|
||||
int languageByte3 = (b[languageIndex+1] & 0x1f) + 0x60;
|
||||
int languageByte = ((buffer[languageIndex] << 1) >> 3) + 0x60;
|
||||
int languageByte2 = ((buffer[languageIndex] & 0x3) << 3) + (buffer[languageIndex + 1] >> 5) + 0x60;
|
||||
int languageByte3 = (buffer[languageIndex + 1] & 0x1f) + 0x60;
|
||||
char x = (char)languageByte;
|
||||
char x2 = (char)languageByte2;
|
||||
char x3 = (char)languageByte3;
|
||||
|
@ -3,26 +3,37 @@ using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Mdia
|
||||
public class Mdia : Box
|
||||
{
|
||||
|
||||
public Mdhd Mdhd { get; private set; }
|
||||
public Minf Minf { get; private set; }
|
||||
public readonly Mdhd Mdhd;
|
||||
public readonly Minf Minf;
|
||||
public readonly string HandlerType = null;
|
||||
|
||||
public bool IsSubtitle
|
||||
{
|
||||
get { return HandlerType == "sbtl"; }
|
||||
|
||||
}
|
||||
|
||||
public bool IsVideo
|
||||
{
|
||||
get { return HandlerType == "vide"; }
|
||||
|
||||
}
|
||||
|
||||
public bool IsAudio
|
||||
{
|
||||
get { return HandlerType == "soun"; }
|
||||
}
|
||||
|
||||
public Mdia(FileStream fs, ulong maximumLength)
|
||||
{
|
||||
var buffer = new byte[8];
|
||||
ulong pos = (ulong)fs.Position;
|
||||
pos = (ulong)fs.Position;
|
||||
while (fs.Position < (long)maximumLength)
|
||||
{
|
||||
int bytesRead;
|
||||
fs.Seek((long)pos, SeekOrigin.Begin);
|
||||
ulong size = Helper.ReadSize(buffer, out bytesRead, fs);
|
||||
if (bytesRead < 8)
|
||||
if (!InitializeSizeAndName(fs))
|
||||
return;
|
||||
string name = Helper.GetString(buffer, 4, 4);
|
||||
pos = ((ulong)(fs.Position)) + size - 8;
|
||||
if (name == "minf")
|
||||
{
|
||||
UInt32 timeScale = 90000;
|
||||
@ -32,16 +43,14 @@ namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
}
|
||||
else if (name == "hdlr")
|
||||
{
|
||||
|
||||
byte[] b = new byte[size - 4];
|
||||
fs.Read(b, 0, b.Length);
|
||||
HandlerType = Helper.GetString(b, 8, 4);
|
||||
buffer = new byte[size - 4];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
HandlerType = GetString(8, 4);
|
||||
}
|
||||
else if (name == "mdhd")
|
||||
{
|
||||
Mdhd = new Mdhd(fs, size);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,29 +3,22 @@ using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Minf
|
||||
public class Minf : Box
|
||||
{
|
||||
|
||||
public Stbl Stbl { get; private set; }
|
||||
public readonly Stbl Stbl;
|
||||
|
||||
public Minf(FileStream fs, ulong maximumLength, UInt32 timeScale)
|
||||
{
|
||||
var buffer = new byte[8];
|
||||
ulong pos = (ulong)fs.Position;
|
||||
pos = (ulong)fs.Position;
|
||||
while (fs.Position < (long)maximumLength)
|
||||
{
|
||||
int bytesRead;
|
||||
fs.Seek((long)pos, SeekOrigin.Begin);
|
||||
ulong size = Helper.ReadSize(buffer, out bytesRead, fs);
|
||||
if (bytesRead < buffer.Length)
|
||||
if (!InitializeSizeAndName(fs))
|
||||
return;
|
||||
string name = Helper.GetString(buffer, 4, 4);
|
||||
|
||||
pos = ((ulong)(fs.Position)) + size - 8;
|
||||
if (name == "stbl")
|
||||
{
|
||||
Stbl = new Stbl(fs, pos, timeScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,37 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Moov
|
||||
public class Moov : Box
|
||||
{
|
||||
public Mvhd Mvhd { get; private set; }
|
||||
public List<Trak> Tracks { get; private set; }
|
||||
public readonly Mvhd Mvhd;
|
||||
public readonly List<Trak> Tracks;
|
||||
|
||||
public Moov(FileStream fs, ulong maximumLength)
|
||||
{
|
||||
Tracks = new List<Trak>();
|
||||
|
||||
var buffer = new byte[8];
|
||||
ulong pos = (ulong) fs.Position;
|
||||
pos = (ulong) fs.Position;
|
||||
while (fs.Position < (long)maximumLength)
|
||||
{
|
||||
int bytesRead;
|
||||
fs.Seek((long)pos, SeekOrigin.Begin);
|
||||
ulong size = Helper.ReadSize(buffer, out bytesRead, fs);
|
||||
if (bytesRead < 8)
|
||||
if (!InitializeSizeAndName(fs))
|
||||
return;
|
||||
string name = Helper.GetString(buffer, 4, 4);
|
||||
pos = ((ulong)(fs.Position)) + size - 8;
|
||||
|
||||
if (name == "trak")
|
||||
{
|
||||
Tracks.Add(new Trak(fs, pos));
|
||||
}
|
||||
else if (name == "mvhd")
|
||||
{
|
||||
Mvhd = new Mvhd(fs, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Mvhd
|
||||
public class Mvhd : Box
|
||||
{
|
||||
|
||||
public readonly uint Duration;
|
||||
public readonly uint TimeScale;
|
||||
|
||||
public Mvhd(FileStream fs, ulong maximumLength)
|
||||
{
|
||||
var buffer = new byte[8];
|
||||
long pos = fs.Position;
|
||||
buffer = new byte[20];
|
||||
int bytesRead = fs.Read(buffer, 0, buffer.Length);
|
||||
if (bytesRead < buffer.Length)
|
||||
return;
|
||||
|
||||
uint TimeScale = GetUInt(12);
|
||||
uint Duration = GetUInt(16);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Stbl
|
||||
public class Stbl : Box
|
||||
{
|
||||
|
||||
public readonly List<string> Texts = new List<string>();
|
||||
@ -13,38 +13,33 @@ namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
|
||||
public Stbl(FileStream fs, ulong maximumLength, UInt32 timeScale)
|
||||
{
|
||||
var buffer = new byte[8];
|
||||
ulong pos = (ulong)fs.Position;
|
||||
pos = (ulong)fs.Position;
|
||||
while (fs.Position < (long)maximumLength)
|
||||
{
|
||||
int bytesRead;
|
||||
fs.Seek((long)pos, SeekOrigin.Begin);
|
||||
ulong size = Helper.ReadSize(buffer, out bytesRead, fs);
|
||||
if (bytesRead < buffer.Length)
|
||||
if (!InitializeSizeAndName(fs))
|
||||
return;
|
||||
string name = Helper.GetString(buffer, 4, 4);
|
||||
pos = ((ulong)(fs.Position)) + size - 8;
|
||||
|
||||
if (name == "stco") // 32-bit
|
||||
{
|
||||
byte[] b = new byte[size - 4];
|
||||
fs.Read(b, 0, b.Length);
|
||||
int version = b[0];
|
||||
uint totalEntries = Helper.GetUInt(b, 4);
|
||||
buffer = new byte[size - 4];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
int version = buffer[0];
|
||||
uint totalEntries = GetUInt(4);
|
||||
|
||||
uint lastOffset = 0;
|
||||
for (int i = 0; i < totalEntries; i++)
|
||||
{
|
||||
uint offset = Helper.GetUInt(b, 8 + i * 4);
|
||||
uint offset = GetUInt(8 + i * 4);
|
||||
if (lastOffset + 5 < offset)
|
||||
{
|
||||
fs.Seek(offset, SeekOrigin.Begin);
|
||||
byte[] data = new byte[150];
|
||||
fs.Read(data, 0, data.Length);
|
||||
uint textSize = Helper.GetUInt(data, 0);
|
||||
uint textSize = GetUInt(data, 0);
|
||||
if (textSize < data.Length - 4)
|
||||
{
|
||||
string text = Helper.GetString(data, 4, (int)textSize - 1);
|
||||
string text = GetString(data, 4, (int)textSize - 1);
|
||||
Texts.Add(text);
|
||||
}
|
||||
}
|
||||
@ -53,24 +48,24 @@ namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
}
|
||||
else if (name == "co64") // 64-bit
|
||||
{
|
||||
byte[] b = new byte[size - 4];
|
||||
fs.Read(b, 0, b.Length);
|
||||
int version = b[0];
|
||||
uint totalEntries = Helper.GetUInt(b, 4);
|
||||
buffer = new byte[size - 4];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
int version = buffer[0];
|
||||
uint totalEntries = GetUInt(4);
|
||||
|
||||
ulong lastOffset = 0;
|
||||
for (int i = 0; i < totalEntries; i++)
|
||||
{
|
||||
ulong offset = Helper.GetUInt64(b, 8 + i * 8);
|
||||
ulong offset = GetUInt64(8 + i * 8);
|
||||
if (lastOffset + 8 < offset)
|
||||
{
|
||||
fs.Seek((long)offset, SeekOrigin.Begin);
|
||||
byte[] data = new byte[150];
|
||||
fs.Read(data, 0, data.Length);
|
||||
uint textSize = Helper.GetUInt(data, 0);
|
||||
uint textSize = GetUInt(data, 0);
|
||||
if (textSize < data.Length - 4)
|
||||
{
|
||||
string text = Helper.GetString(data, 4, (int)textSize - 1);
|
||||
string text = GetString(data, 4, (int)textSize - 1);
|
||||
Texts.Add(text);
|
||||
}
|
||||
}
|
||||
@ -79,27 +74,27 @@ namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
}
|
||||
else if (name == "stsz") // sample sizes
|
||||
{
|
||||
byte[] b = new byte[size - 4];
|
||||
fs.Read(b, 0, b.Length);
|
||||
int version = b[0];
|
||||
uint uniformSizeOfEachSample = Helper.GetUInt(b, 4);
|
||||
uint numberOfSampleSizes = Helper.GetUInt(b, 8);
|
||||
buffer = new byte[size - 4];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
int version = buffer[0];
|
||||
uint uniformSizeOfEachSample = GetUInt(4);
|
||||
uint numberOfSampleSizes = GetUInt(8);
|
||||
for (int i = 0; i < numberOfSampleSizes; i++)
|
||||
{
|
||||
uint sampleSize = Helper.GetUInt(b, 12 + i * 4);
|
||||
uint sampleSize = GetUInt(12 + i * 4);
|
||||
}
|
||||
}
|
||||
else if (name == "stts") // sample table time to sample map
|
||||
{
|
||||
byte[] b = new byte[size - 4];
|
||||
fs.Read(b, 0, b.Length);
|
||||
int version = b[0];
|
||||
uint numberOfSampleTimes = Helper.GetUInt(b, 4);
|
||||
buffer = new byte[size - 4];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
int version = buffer[0];
|
||||
uint numberOfSampleTimes = GetUInt(4);
|
||||
double totalTime = 0;
|
||||
for (int i = 0; i < numberOfSampleTimes; i++)
|
||||
{
|
||||
uint sampleCount = Helper.GetUInt(b, 8 + i * 8);
|
||||
uint sampleDelta = Helper.GetUInt(b, 12 + i * 8);
|
||||
uint sampleCount = GetUInt(8 + i * 8);
|
||||
uint sampleDelta = GetUInt(12 + i * 8);
|
||||
totalTime += (double)(sampleDelta / (double)timeScale);
|
||||
if (StartTimeCodes.Count <= EndTimeCodes.Count)
|
||||
StartTimeCodes.Add(totalTime);
|
||||
@ -109,15 +104,15 @@ namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
}
|
||||
else if (name == "stsc") // sample table sample to chunk map
|
||||
{
|
||||
byte[] b = new byte[size - 4];
|
||||
fs.Read(b, 0, b.Length);
|
||||
int version = b[0];
|
||||
uint numberOfSampleTimes = Helper.GetUInt(b, 4);
|
||||
buffer = new byte[size - 4];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
int version = buffer[0];
|
||||
uint numberOfSampleTimes = GetUInt(4);
|
||||
for (int i = 0; i < numberOfSampleTimes; i++)
|
||||
{
|
||||
uint firstChunk = Helper.GetUInt(b, 8 + i * 12);
|
||||
uint samplesPerChunk = Helper.GetUInt(b, 12 + i * 12);
|
||||
uint sampleDescriptionIndex = Helper.GetUInt(b, 16 + i * 12);
|
||||
uint firstChunk = GetUInt(8 + i * 12);
|
||||
uint samplesPerChunk = GetUInt(12 + i * 12);
|
||||
uint sampleDescriptionIndex = GetUInt(16 + i * 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Tkhd
|
||||
public class Tkhd : Box
|
||||
{
|
||||
|
||||
public readonly uint Width;
|
||||
public readonly uint Height;
|
||||
|
||||
public Tkhd(FileStream fs, ulong maximumLength)
|
||||
{
|
||||
buffer = new byte[38];
|
||||
int bytesRead = fs.Read(buffer, 0, buffer.Length);
|
||||
if (bytesRead < buffer.Length)
|
||||
return;
|
||||
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 04).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 06).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 08).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 10).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 12).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 14).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 16).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 19).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 20).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 22).ToString());
|
||||
//System.Windows.Forms.MessageBox.Show(Helper.GetUInt(buffer, 24).ToString());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,29 +3,25 @@ using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4.Boxes
|
||||
{
|
||||
public class Trak
|
||||
public class Trak : Box
|
||||
{
|
||||
|
||||
public Mdia Mdia { get; private set; }
|
||||
public readonly Mdia Mdia;
|
||||
public readonly Tkhd Tkhd;
|
||||
|
||||
public Trak(FileStream fs, ulong maximumLength)
|
||||
{
|
||||
var buffer = new byte[8];
|
||||
ulong pos = (ulong)fs.Position;
|
||||
pos = (ulong)fs.Position;
|
||||
while (fs.Position < (long)maximumLength)
|
||||
{
|
||||
int bytesRead;
|
||||
fs.Seek((long)pos, SeekOrigin.Begin);
|
||||
ulong size = Helper.ReadSize(buffer, out bytesRead, fs);
|
||||
if (bytesRead < buffer.Length)
|
||||
if (!InitializeSizeAndName(fs))
|
||||
return;
|
||||
string name = Helper.GetString(buffer, 4, 4);
|
||||
|
||||
pos = ((ulong)(fs.Position)) + size - 8;
|
||||
if (name == "mdia")
|
||||
{
|
||||
Mdia = new Mdia(fs, pos);
|
||||
}
|
||||
else if (name == "tkhd")
|
||||
Tkhd = new Tkhd(fs, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Nikse.SubtitleEdit.Logic.Mp4.Boxes;
|
||||
using System;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Logic.Mp4
|
||||
{
|
||||
/// <summary>
|
||||
/// http://wiki.multimedia.cx/index.php?title=QuickTime_container
|
||||
/// </summary>
|
||||
public class Mp4Parser
|
||||
public class Mp4Parser : Box
|
||||
{
|
||||
public string FileName { get; private set; }
|
||||
public Moov Moov { get; private set; }
|
||||
@ -20,7 +20,7 @@ namespace Nikse.SubtitleEdit.Logic.Mp4
|
||||
{
|
||||
foreach (var trak in Moov.Tracks)
|
||||
{
|
||||
if (trak.Mdia != null && trak.Mdia.HandlerType == "sbtl" && trak.Mdia.Minf != null && trak.Mdia.Minf.Stbl != null)
|
||||
if (trak.Mdia != null && trak.Mdia.IsSubtitle && trak.Mdia.Minf != null && trak.Mdia.Minf.Stbl != null)
|
||||
{
|
||||
list.Add(trak);
|
||||
}
|
||||
@ -29,6 +29,35 @@ namespace Nikse.SubtitleEdit.Logic.Mp4
|
||||
return list;
|
||||
}
|
||||
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Moov != null && Moov.Mvhd != null && Moov.Mvhd.TimeScale > 0)
|
||||
return TimeSpan.FromSeconds((double)Moov.Mvhd.Duration / Moov.Mvhd.TimeScale);
|
||||
return new TimeSpan();
|
||||
}
|
||||
}
|
||||
|
||||
public System.Drawing.Point VideoResolution
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Moov != null && Moov.Tracks != null)
|
||||
{
|
||||
foreach (var trak in Moov.Tracks)
|
||||
{
|
||||
if (trak != null && trak.Mdia != null && trak.Tkhd != null)
|
||||
{
|
||||
if (trak.Mdia.IsVideo)
|
||||
return new System.Drawing.Point((int)trak.Tkhd.Width, (int)trak.Tkhd.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new System.Drawing.Point(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public Mp4Parser(string fileName)
|
||||
{
|
||||
FileName = fileName;
|
||||
@ -46,14 +75,13 @@ namespace Nikse.SubtitleEdit.Logic.Mp4
|
||||
private void ParseMp4(FileStream fs)
|
||||
{
|
||||
int count = 0;
|
||||
var buffer = new byte[8];
|
||||
ulong pos = 0;
|
||||
int bytesRead = 8;
|
||||
while (bytesRead == 8)
|
||||
buffer = new byte[8];
|
||||
pos = 0;
|
||||
bool moreBytes = true;
|
||||
while (moreBytes)
|
||||
{
|
||||
fs.Seek((long)pos, SeekOrigin.Begin);
|
||||
ulong size = Helper.ReadSize(buffer, out bytesRead, fs);
|
||||
string name = Helper.GetString(buffer, 4, 4);
|
||||
moreBytes = InitializeSizeAndName(fs);
|
||||
pos = ((ulong) (fs.Position)) + size - 8;
|
||||
if (name == "moov")
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user