support exporting VideoClips with a size above 2gb. close #765

This commit is contained in:
Perfare 2021-07-02 03:26:46 +08:00
parent 17b91984d6
commit 850ba63a10
7 changed files with 47 additions and 36 deletions

View File

@ -27,8 +27,8 @@ namespace AssetStudio
public AudioCompressionFormat m_CompressionFormat; public AudioCompressionFormat m_CompressionFormat;
public string m_Source; public string m_Source;
public ulong m_Offset; public long m_Offset; //ulong
public long m_Size; public long m_Size; //ulong
public ResourceReader m_AudioData; public ResourceReader m_AudioData;
public AudioClip(ObjectReader reader) : base(reader) public AudioClip(ObjectReader reader) : base(reader)
@ -74,7 +74,7 @@ namespace AssetStudio
//StreamedResource m_Resource //StreamedResource m_Resource
m_Source = reader.ReadAlignedString(); m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadUInt64(); m_Offset = reader.ReadInt64();
m_Size = reader.ReadInt64(); m_Size = reader.ReadInt64();
m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32(); m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32();
} }
@ -82,11 +82,11 @@ namespace AssetStudio
ResourceReader resourceReader; ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_Source)) if (!string.IsNullOrEmpty(m_Source))
{ {
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, (int)m_Size); resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, m_Size);
} }
else else
{ {
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size); resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_Size);
} }
m_AudioData = resourceReader; m_AudioData = resourceReader;
} }

View File

@ -681,7 +681,7 @@ namespace AssetStudio
{ {
if (m_VertexData.m_VertexCount > 0) if (m_VertexData.m_VertexCount > 0)
{ {
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size); var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
m_VertexData.m_DataSize = resourceReader.GetData(); m_VertexData.m_DataSize = resourceReader.GetData();
} }
} }

View File

@ -4,7 +4,7 @@ namespace AssetStudio
{ {
public class StreamingInfo public class StreamingInfo
{ {
public ulong offset; public long offset; //ulong
public uint size; public uint size;
public string path; public string path;
@ -14,7 +14,7 @@ namespace AssetStudio
if (version[0] >= 2020) //2020.1 and up if (version[0] >= 2020) //2020.1 and up
{ {
offset = reader.ReadUInt64(); offset = reader.ReadInt64();
} }
else else
{ {
@ -134,7 +134,7 @@ namespace AssetStudio
ResourceReader resourceReader; ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_StreamData?.path)) if (!string.IsNullOrEmpty(m_StreamData?.path))
{ {
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size); resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
} }
else else
{ {

View File

@ -5,14 +5,14 @@ namespace AssetStudio
public class StreamedResource public class StreamedResource
{ {
public string m_Source; public string m_Source;
public ulong m_Offset; public long m_Offset; //ulong
public ulong m_Size; public long m_Size; //ulong
public StreamedResource(BinaryReader reader) public StreamedResource(BinaryReader reader)
{ {
m_Source = reader.ReadAlignedString(); m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadUInt64(); m_Offset = reader.ReadInt64();
m_Size = reader.ReadUInt64(); m_Size = reader.ReadInt64();
} }
} }
@ -60,11 +60,11 @@ namespace AssetStudio
ResourceReader resourceReader; ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_ExternalResources.m_Source)) if (!string.IsNullOrEmpty(m_ExternalResources.m_Source))
{ {
resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, (int)m_ExternalResources.m_Size); resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, m_ExternalResources.m_Size);
} }
else else
{ {
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_ExternalResources.m_Size); resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_ExternalResources.m_Size);
} }
m_VideoData = resourceReader; m_VideoData = resourceReader;
} }

View File

@ -58,7 +58,7 @@ namespace AssetStudio
} }
} }
public bool IsSerializedFile() private bool IsSerializedFile()
{ {
var fileSize = BaseStream.Length; var fileSize = BaseStream.Length;
if (fileSize < 20) if (fileSize < 20)

View File

@ -8,41 +8,37 @@ namespace AssetStudio
private string path; private string path;
private SerializedFile assetsFile; private SerializedFile assetsFile;
private long offset; private long offset;
private int size; private long size;
private BinaryReader reader; private BinaryReader reader;
public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
public ResourceReader(string path, SerializedFile assetsFile, ulong offset, int size)
{ {
needSearch = true; needSearch = true;
this.path = path; this.path = path;
this.assetsFile = assetsFile; this.assetsFile = assetsFile;
this.offset = (long)offset; this.offset = offset;
this.size = size; this.size = size;
} }
public ResourceReader(BinaryReader reader, long offset, int size) public ResourceReader(BinaryReader reader, long offset, long size)
{ {
this.reader = reader; this.reader = reader;
this.offset = offset; this.offset = offset;
this.size = size; this.size = size;
} }
public byte[] GetData() private BinaryReader GetReader()
{ {
if (needSearch) if (needSearch)
{ {
var resourceFileName = Path.GetFileName(path); var resourceFileName = Path.GetFileName(path);
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader)) if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader))
{ {
needSearch = false; needSearch = false;
reader.BaseStream.Position = offset; return reader;
return reader.ReadBytes(size);
} }
var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName); var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName);
var resourceFilePath = assetsFileDirectory + Path.DirectorySeparatorChar + resourceFileName; var resourceFilePath = Path.Combine(assetsFileDirectory, resourceFileName);
if (!File.Exists(resourceFilePath)) if (!File.Exists(resourceFilePath))
{ {
var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories); var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories);
@ -53,18 +49,34 @@ namespace AssetStudio
} }
if (File.Exists(resourceFilePath)) if (File.Exists(resourceFilePath))
{ {
reader = new BinaryReader(File.OpenRead(resourceFilePath));
needSearch = false; needSearch = false;
reader = new BinaryReader(File.OpenRead(resourceFilePath));
assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader); assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader);
reader.BaseStream.Position = offset; return reader;
return reader.ReadBytes(size);
} }
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}"); throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
} }
else
{
return reader;
}
}
reader.BaseStream.Position = offset; public byte[] GetData()
return reader.ReadBytes(size); {
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
return binaryReader.ReadBytes((int)size);
}
public void WriteData(string path)
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
using (var writer = File.OpenWrite(path))
{
binaryReader.BaseStream.CopyTo(writer, size);
}
} }
} }
} }

View File

@ -205,12 +205,11 @@ namespace AssetStudioGUI
public static bool ExportVideoClip(AssetItem item, string exportPath) public static bool ExportVideoClip(AssetItem item, string exportPath)
{ {
var m_VideoClip = (VideoClip)item.Asset; var m_VideoClip = (VideoClip)item.Asset;
var m_VideoData = m_VideoClip.m_VideoData.GetData(); if (m_VideoClip.m_ExternalResources.m_Size > 0)
if (m_VideoData != null && m_VideoData.Length != 0)
{ {
if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath)) if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath))
return false; return false;
File.WriteAllBytes(exportFullPath, m_VideoData); m_VideoClip.m_VideoData.WriteData(exportFullPath);
return true; return true;
} }
return false; return false;