/// <summary> /// Write the sample or stream sample in the correct way given the payload and the segment /// compression settings. In the case of uncompressed video, also reconfigure the writer input properties /// if the newstream flag is set. Keyframe and discontinuity flags are only relevant when writing /// compressed video. /// </summary> /// <param name="payload"></param> /// <param name="sample"></param> /// <param name="timestamp"></param> /// <param name="newstream"></param> /// <returns></returns> private void writeSample(PayloadType payload, BufferChunk sample, ulong timestamp, bool newstream, bool keyframe, bool discontinuity) { if (payload == PayloadType.dynamicAudio) { if (norecompression) { writer.WriteCompressedAudio(timestamp, (uint)sample.Length, (byte[])sample); } else { writer.WriteAudio((uint)sample.Length, sample, timestamp); } } else if (payload == PayloadType.dynamicVideo) { if (norecompression) { writer.WriteCompressedVideo(timestamp, (uint)sample.Length, (byte[])sample, keyframe, discontinuity); } else { if (newstream) { //PRI3: don't need to reconfig unless MT changed. Probably does no harm though if (useSlideStream) { //writer.ConfigSlideStreamVideo(slideStream.UncompressedMediaType); writer.ConfigVideo(slideStream.UncompressedMediaType); } else { writer.ConfigVideo(videoStream.GetUncompressedVideoMediaType()); } } writer.WriteVideo((uint)sample.Length, sample, timestamp); } } }
/// <summary> /// Write each stream from DBStreamPlayer to a WM file, then create FileStreamPlayers for each. /// It is necessary to do this before reading uncompressed samples, or using any of the /// methods that return uncompressed MediaTypes. /// This can be a long-running process. It can be cancelled with the Stop method. /// </summary> /// <returns>False if we failed to configure the native profile</returns> public bool ToRawWMFile(ProgressTracker progressTracker) { if (cancel) { return(true); } String tmpfile = ""; fileStreamPlayers = new FileStreamPlayer[streamPlayers.Length]; for (int i = 0; i < streams.Length; i++) { streamProfileData = ProfileUtility.StreamIdToProfileData(streams[i], payload); if (payload == PayloadType.dynamicVideo) { tmpfile = Utility.GetTempFilePath("wmv"); //nativeProfile = ProfileUtility.MakeNativeVideoProfile(streams[i]); } else { tmpfile = Utility.GetTempFilePath("wma"); //nativeProfile = ProfileUtility.MakeNativeAudioProfile(streams[i]); } WMWriter wmWriter = new WMWriter(); wmWriter.Init(); //if (!wmWriter.ConfigProfile(nativeProfile,"",0)) if (!wmWriter.ConfigProfile(StreamProfileData)) { return(false); } wmWriter.ConfigFile(tmpfile); wmWriter.ConfigNullProps(); //wmWriter.SetCodecInfo(payload); wmWriter.Start(); long streamTime = long.MaxValue; long refTime = 0; long endTime = 0; long lastWriteTime = 0; BufferChunk frame; BufferChunk sample; bool keyframe; bool discontinuity; discontinuity = true; //Catch exceptions to work around the rare case of data corruption. //Oddly in one case where this occurred it did not occur if the segments were short enough while (streamPlayers[i].GetNextFrame(out frame, out streamTime)) { try { sample = ProfileUtility.FrameToSample(frame, out keyframe); } catch { DateTime dt = new DateTime(streamTime); Console.WriteLine("Possible data corruption in stream: " + this.payload + ";" + this.cname + " at " + dt.ToString() + " (" + streamTime.ToString() + ")"); continue; } if (refTime == 0) { refTime = streamTime; } lastWriteTime = streamTime - refTime; try { if (payload == PayloadType.dynamicVideo) { //Debug.WriteLine("Write video: " + (streamTime-refTime).ToString() + ";length=" + sample.Length.ToString()); wmWriter.WriteCompressedVideo((ulong)(streamTime - refTime), (uint)sample.Length, (byte[])sample, keyframe, discontinuity); } else { //Debug.WriteLine("Write audio: " + (streamTime-refTime).ToString() + ";length=" + sample.Length.ToString()); wmWriter.WriteCompressedAudio((ulong)(streamTime - refTime), (uint)sample.Length, (byte[])sample); } } catch { DateTime dt = new DateTime(streamTime); Console.WriteLine("Failed to write. Possible data corruption in stream: " + this.payload + ";" + this.cname + " at " + dt.ToString() + " (" + streamTime.ToString() + ")"); } if (discontinuity) { discontinuity = false; } endTime = streamTime; if (cancel) { break; } progressTracker.CurrentValue = (int)(lastWriteTime / Constants.TicksPerSec); //Debug.WriteLine("StreamMgr.ToRawWMFile: ProgressTracker currentValue=" + progressTracker.CurrentValue.ToString() + // ";streamTime=" + streamTime.ToString()); } wmWriter.Stop(); wmWriter.Cleanup(); wmWriter = null; fileStreamPlayers[i] = new FileStreamPlayer(tmpfile, refTime, endTime, false, streams[i]); if (cancel) { break; } } return(true); }