static private Deserialize ( Stream raw, StreamCapabilities, _streamCapabilities ) : bool | ||
raw | Stream | |
_streamCapabilities | StreamCapabilities, | |
return | bool |
public virtual bool Initialize(int clientSideBufferLength) { //1. Check to see if we have an universal seeking file var seekFilePath = Name + "." + MEDIA_TYPE_SEEK; if (!File.Exists(seekFilePath)) { var meta = Variant.GetMap(new VariantMapHelper { { META_SERVER_FULL_PATH, Name } }); if (!ResolveCompleteMetadata(ref meta)) { Logger.FATAL("Unable to generate metadata"); return(false); } } //2. Open the seek file _pSeekFile = MediaFile.Initialize(seekFilePath); if (_pSeekFile == null) { Logger.FATAL("Unable to open seeking file {0}", seekFilePath); return(false); } //3. read stream capabilities var streamCapabilitiesSize = _pSeekFile.Br.ReadUInt32(); //var raw = new MemoryStream(); //_pSeekFile.CopyPartTo(raw, (int)streamCapabilitiesSize); if (streamCapabilitiesSize < 14 || !StreamCapabilities.Deserialize(_pSeekFile.DataStream, Capabilities)) { Logger.FATAL("Unable to deserialize stream Capabilities. Please delete {0} and {1} files so they can be regenerated", Name + "." + MEDIA_TYPE_SEEK, Name + "." + MEDIA_TYPE_META); return(false); } //4. compute offsets _seekBaseOffset = _pSeekFile.Position; _framesBaseOffset = _seekBaseOffset + 4; //5. Compute the optimal window size by reading the biggest frame size //from the seek file. if (!_pSeekFile.SeekTo(_pSeekFile.Length - 8)) { Logger.FATAL("Unable to seek to {0} position", _pSeekFile.Position - 8); return(false); } ulong maxFrameSize = _pSeekFile.Br.ReadUInt64(); if (!_pSeekFile.SeekBegin()) { Logger.FATAL("Unable to seek to beginning of the file"); return(false); } //3. Open the media file var windowSize = (uint)maxFrameSize * 16; //windowSize = windowSize < 65536 ? 65536 : windowSize; //windowSize = (windowSize > (1024 * 1024)) ? (windowSize / 2) : windowSize; _pFile = MediaFile.Initialize(Name); //4. Read the frames count from the file if (!_pSeekFile.SeekTo(_seekBaseOffset)) { Logger.FATAL("Unable to seek to _seekBaseOffset: {0}", _seekBaseOffset); return(false); } _totalFrames = _pSeekFile.Br.ReadUInt32(); _timeToIndexOffset = _framesBaseOffset + _totalFrames * MediaFrame.MediaFrameSize; //5. Set the client side buffer length _clientSideBufferLength = clientSideBufferLength; //6. Create the timer _pTimer = new InFileStreamTimer(this); _pTimer.EnqueueForTimeEvent((uint)(_clientSideBufferLength - _clientSideBufferLength / 3)); //7. Done return(true); }
public Variant GetMetaData(string streamName, bool extractInnerMetadata, Variant configuration) { bool keyframeSeek = configuration[Defines.CONF_APPLICATION_KEYFRAMESEEK]; int clientSideBuffer = configuration[Defines.CONF_APPLICATION_CLIENTSIDEBUFFER]; var seekGranularity = (uint)((double)configuration[Defines.CONF_APPLICATION_SEEKGRANULARITY] * 1000); bool renameBadFiles = configuration[Defines.CONF_APPLICATION_RENAMEBADFILES]; bool externSeekGenerator = configuration[Defines.CONF_APPLICATION_EXTERNSEEKGENERATOR]; var result = Variant.Get(); result[Defines.META_REQUESTED_STREAM_NAME] = streamName; result[Defines.CONF_APPLICATION_KEYFRAMESEEK] = keyframeSeek; result[Defines.CONF_APPLICATION_CLIENTSIDEBUFFER] = clientSideBuffer; result[Defines.CONF_APPLICATION_SEEKGRANULARITY] = seekGranularity; result[Defines.CONF_APPLICATION_RENAMEBADFILES] = renameBadFiles; result[Defines.CONF_APPLICATION_EXTERNSEEKGENERATOR] = externSeekGenerator; var parts = streamName.Split(':'); if (parts.Length != 1 && parts.Length != 2 && parts.Length != 5) { Logger.FATAL("Invalid stream name format:{0}", streamName); return(result); } result[Defines.META_MEDIA_TYPE] = parts.Length == 1 ? Defines.MEDIA_TYPE_LIVE_OR_FLV : parts[0].ToLower(); var searchFor = ""; switch ((string)result[Defines.META_MEDIA_TYPE]) { case Defines.MEDIA_TYPE_LIVE_OR_FLV: searchFor = parts[0] + ".flv"; break; case Defines.MEDIA_TYPE_MP3: searchFor = parts[1] + ".mp3"; break; default: searchFor = parts[1]; break; } result[Defines.META_SERVER_FILE_NAME] = searchFor; var _mediaFolder = Application.MediaPath; result[Defines.META_SERVER_MEDIA_DIR] = _mediaFolder; result[Defines.META_SERVER_FULL_PATH] = searchFor[0] == Path.DirectorySeparatorChar ? (searchFor.StartsWith(_mediaFolder.NormalizePath()) ? searchFor : "") : _mediaFolder.NormalizePath(searchFor); if (string.IsNullOrEmpty(result[Defines.META_SERVER_FULL_PATH])) { return(result); } var metaPath = result[Defines.META_SERVER_FULL_PATH] + "." + Defines.MEDIA_TYPE_META; var seekPath = result[Defines.META_SERVER_FULL_PATH] + "." + Defines.MEDIA_TYPE_SEEK; var regenerateFiles = true; if (File.Exists(metaPath) && File.Exists(seekPath)) { var capabilities = new StreamCapabilities(); var originalServerFullPath = (string)result[Defines.META_SERVER_FULL_PATH]; regenerateFiles = (new FileInfo(metaPath).LastWriteTime < new FileInfo(result[Defines.META_SERVER_FULL_PATH]).LastWriteTime) || (new FileInfo(seekPath).LastWriteTime < new FileInfo(result[Defines.META_SERVER_FULL_PATH]).LastWriteTime) || !Variant.DeserializeFromFile(metaPath, out result) || (!StreamCapabilities.Deserialize(seekPath, capabilities)); regenerateFiles |= (result[Defines.META_SERVER_FULL_PATH] == null) || ((string)result[Defines.META_SERVER_FULL_PATH] != originalServerFullPath) || (result[Defines.CONF_APPLICATION_KEYFRAMESEEK] == null) || ((bool)result[Defines.CONF_APPLICATION_KEYFRAMESEEK] != keyframeSeek) || (result[Defines.CONF_APPLICATION_CLIENTSIDEBUFFER] == null) || ((int)result[Defines.CONF_APPLICATION_CLIENTSIDEBUFFER] != clientSideBuffer) || (result[Defines.CONF_APPLICATION_SEEKGRANULARITY] == null) || ((uint)result[Defines.CONF_APPLICATION_SEEKGRANULARITY] != seekGranularity); if (regenerateFiles) { result[Defines.META_SERVER_FULL_PATH] = originalServerFullPath; result[Defines.CONF_APPLICATION_KEYFRAMESEEK] = keyframeSeek; result[Defines.CONF_APPLICATION_CLIENTSIDEBUFFER] = clientSideBuffer; result[Defines.CONF_APPLICATION_SEEKGRANULARITY] = seekGranularity; } } if (!regenerateFiles) { result[Defines.META_REQUESTED_STREAM_NAME] = streamName; return(result); } this.Log().Info("Generate seek/meta for file {0}", result[Defines.META_SERVER_FULL_PATH]); //8. We either have a bad meta file or we don't have it at all. Build it if (extractInnerMetadata) { if (!BaseInFileStream.ResolveCompleteMetadata(ref result)) { Logger.FATAL("Unable to get metadata. Partial result:\n{0}", result); return(Variant.Get()); } } result.SerializeToFile(metaPath); return(result); }