/// <summary> /// 指定したトラックタイプのトラックIDを取得する。 /// </summary> /// <param name="trackType">トラックタイプ</param> /// <returns>該当するトラックが見つかった場合にそのトラックIDを返す。見つからなかった場合は-1</returns> private int GetTrackID(MOOV.TrackType trackType) { if (_moov.Traks != null) { for (int i = 0; i < _moov.Traks.Length; i++) { if (_moov.Traks[i] != null && _moov.Traks[i].TrackType == trackType) { return(i); } } } return(-1); }
/// <summary> /// トラックを作成する。 /// </summary> /// <param name="trackType">トラックタイプ</param> /// <returns>作成に成功したか?</returns> private bool CreateTrack(MOOV.TrackType trackType) { if (trackType == MOOV.TrackType.None || trackType == MOOV.TrackType.MaxSize) { return(false); } uint trackID = 1; if (_moov.Traks == null) { _moov.Traks = new MOOV.TRAK[1]; } else { Array.Resize(ref _moov.Traks, _moov.Traks.Length + 1); trackID = (uint)_moov.Traks.Length; } _moov.Mvhd.TimeScale = _timeScale; _moov.Mvhd.NextTrackID = trackID + 1; MOOV.TRAK track = new MOOV.TRAK() { TrackType = trackType, }; track.Tkhd.TrackId = trackID; //if (trackType == MOOV.TrackType.Text) //{ // track.Tkhd.Height = 64; //} track.Mdia.Mdhd.TimeScale = _timeScale; track.Mdia.Hdlr.ComponentType = MOOV.TRAK.MDIA.HDLR.ComponentTypeNameList.mhlr.ToString(); track.Mdia.Hdlr.ComponentSubtype = ((MOOV.TRAK.MDIA.HDLR.ComponentSubtypeNameList)trackType).ToString(); switch (trackType) { case MOOV.TrackType.Video: track.Mdia.Minf.Vmhd = new MOOV.TRAK.MDIA.MINF.VMHD(); break; case MOOV.TrackType.Audio: track.Mdia.Minf.Smhd = new MOOV.TRAK.MDIA.MINF.SMHD(); break; //case MOOV.TrackType.Text: // track.Mdia.Minf.Gmhd = new MOOV.TRAK.MDIA.MINF.GMHD(); // break; default: break; } track.Mdia.Minf.Hdlr.ComponentType = MOOV.TRAK.MDIA.HDLR.ComponentTypeNameList.dhlr.ToString(); track.Mdia.Minf.Hdlr.ComponentSubtype = MOOV.TRAK.MDIA.HDLR.ComponentSubtypeNameList.alis.ToString(); track.Mdia.Minf.Dinf.Dref.DataReferenceInformations.Add( new MOOV.TRAK.MDIA.MINF.DINF.DREF.DataReferenceInformation() { DataReferenceInformationType = MOOV.TRAK.MDIA.MINF.DINF.DREF.DataReferenceInformation.DataReferenceInformationTypeList.alis.ToString() }); _moov.Traks[_moov.Traks.Length - 1] = track; //// コーデック情報設定 //SetCodecInformation(CreateTX3GCodecInformation(), MOOV.TrackType.Text); return(true); }
/// <summary> /// コーデック情報を設定する。 /// </summary> /// <param name="codecInformation">コーデック情報(stsd atom内に設定するデータそのものを指定する)</param> /// <param name="trackType">トラックタイプ</param> /// <returns>設定に成功したか?</returns> public bool SetCodecInformation(byte[] codecInformation, MOOV.TrackType trackType) { if (codecInformation == null) { return(false); } int trackID = GetTrackID(trackType); if (trackID < 0) { return(false); } if (_moov.Traks[trackID].Mdia.Minf.Stbl.Stsd.SampleDescriptions.Count > 0) { if (_moov.Traks[trackID].Mdia.Minf.Stbl.Stsd.SampleDescriptions[_moov.Traks[trackID].Mdia.Minf.Stbl.Stsd.SampleDescriptions.Count - 1].SequenceEqual(codecInformation) == true) { return(true); } } bool isSuccess = false; if (trackType == MOOV.TrackType.Video) { // ビデオトラックの場合はコーデック情報からイメージサイズを取得し、トラックに反映する。 if (codecInformation.LongLength >= 36) { byte[] typeBytes = new byte[4]; string type = string.Empty; Array.Copy(codecInformation, 4, typeBytes, 0, typeBytes.Length); type = Encoding.ASCII.GetString(typeBytes); if (type == "jpeg" || type == "avc1") { byte[] sizeBytes = new byte[2]; Array.Copy(codecInformation, 32, sizeBytes, 0, sizeBytes.Length); Array.Reverse(sizeBytes); ushort width = BitConverter.ToUInt16(sizeBytes, 0); Array.Copy(codecInformation, 34, sizeBytes, 0, sizeBytes.Length); Array.Reverse(sizeBytes); ushort height = BitConverter.ToUInt16(sizeBytes, 0); // イメージサイズ設定 _moov.Traks[trackID].Tkhd.Width = width; _moov.Traks[trackID].Tkhd.Height = height; //// テキストトラックの配置も設定 //int textTrackID = GetTrackID(MOOV.TrackType.Text); //if (textTrackID >= 0) //{ // _moov.Traks[textTrackID].Tkhd.Width = width; // Array.Copy(GetReverseBytes(height), 0, _moov.Traks[textTrackID].Tkhd.MatrixStructure, 28, 2); //} isSuccess = true; } } } else { isSuccess = true; } if (isSuccess == true) { _moov.Traks[trackID].Mdia.Minf.Stbl.Stsd.SampleDescriptions.Add(codecInformation); } return(isSuccess); }