public long CurrentPosition() { if ((m_itCurrent == m_Clips.Count) || !m_bActive) { return(m_tStartPosition); } double dTime = 0; m_pController.GetSegmentTime(out dTime); long tNow = (long)(dTime * 10000000); ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; // this is relative to the start position within this particular clip. // Did we start at the beginning of this clip? if (m_tStartPosition > ce.GetStartPosition()) { // no, we started some distance into the clip tNow += (m_tStartPosition - ce.GetStartPosition()); } // offset from start of this clip to start of entire sequence tNow += ce.GetStartPosition(); if ((tNow < 0) && m_bLoop) { // current time is near end of previous loop ce = (ClipEntry)m_Clips[m_Clips.Count - 1]; tNow += ce.GetStartPosition() + ce.Duration(); } return(tNow); }
public int Play() { // make all graphs active int hr = S_OK; if (!m_bActive) { UpdateDuration(); hr = Pause(); } ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; if (ce.Graph() == null) { hr = E_FAIL; } if (hr >= 0) { IMediaControl pMC = m_pRenderGraph as IMediaControl; hr = pMC.Run(); } return(hr); }
private async Task <ClipEntry> CompileDocumentClip(CompilingProgressManager reporter, DocumentClipDescriptor clip, DirectoryInfo pesDir) { byte tId = 0; var tPgsTaskList = new List <Task <PgsEntryDescriptor> >(); foreach (var iTrack in clip.Tracks) { tPgsTaskList.Add(Task.Run( () => CompileTrack(reporter, clip, iTrack, pesDir, Muxer.GetPgsPid(tId++)) )); } await Task.WhenAll(tPgsTaskList); TimeSpan tMaxLength = tPgsTaskList.Max(xPgsTask => xPgsTask.Result.Length); ClipEntry tClipEntry = new ClipEntry(clip.ClipId, clip.InTimeOffset, clip.InTimeOffset + tMaxLength); foreach (var iPgsTask in tPgsTaskList) { var tPgsDesc = iPgsTask.Result; var tPgs = new PgsEntry(tPgsDesc.Pid, tPgsDesc.PesFile, tPgsDesc.Lang); tClipEntry.AddPgs(tPgs); } return(tClipEntry); }
/// <summary> /// Load audio clip to memory /// </summary> /// <param name="clipEntry">ClipEntry object containing audio clip</param> public void LoadSound(ClipEntry clipEntry) { if (!clipEntry.loaded) { clipEntry.loaded = true; clipEntry.clip = Resources.Load <AudioClip>(clipEntry.path); } }
/// <summary> /// Unload audio clip from memory /// </summary> /// <param name="clipEntry">ClipEntry object containing audio clip</param> public void UnloadSound(ClipEntry clipEntry) { if (clipEntry.loaded) { clipEntry.loaded = false; clipEntry.clip = null; } }
public int AddClip(string path, out ClipEntry pClip) { int it = m_Clips.Count; pClip = new ClipEntry(); m_Clips.Add(pClip); int hr = pClip.Create(m_pController, path); // if we expect both audio and video, then all clips // must have both audio and video. // If the first clip is video only, then switch // to video-only automatically if ((hr == VFW_E_UNSUPPORTED_AUDIO) && (m_Clips.Count == 1)) { // new controller, different options (only one video stream) if (m_pController != null) { Marshal.ReleaseComObject(m_pController); m_pController = null; } m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(m_hwndApp, m_msgSegment); m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.SetBufferMinimum(200); // try again hr = pClip.Create(m_pController, path); } if (hr >= 0) { pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); // if this is the first clip, create the render graph if (m_Clips.Count == 1) { m_pRenderGraph = new FilterGraph() as IGraphBuilder; hr = m_pController.CreateRenderGraph(pClip.SinkFilter(), m_pRenderGraph, out m_pRenderGraphSourceFilter); if (hr >= 0 && m_hwndApp != IntPtr.Zero) { IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; if (pME != null) { pME.SetNotifyWindow(m_hwndApp, m_msgEvent, IntPtr.Zero); } } } } else { pClip.Dispose(); m_Clips.RemoveAt(it); } return(hr); }
public int AddClip(string path, out ClipEntry pClip) { int it = m_Clips.Count; pClip = new ClipEntry(); m_Clips.Add(pClip); int hr = pClip.Create(m_pController, path); // if we expect both audio and video, then all clips // must have both audio and video. // If the first clip is video only, then switch // to video-only automatically if ((hr == VFW_E_UNSUPPORTED_AUDIO) && (m_Clips.Count == 1)) { // new controller, different options (only one video stream) if (m_pController != null) { Marshal.ReleaseComObject(m_pController); m_pController = null; } m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(m_hwndApp, m_msgSegment); m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.SetBufferMinimum(200); // try again hr = pClip.Create(m_pController, path); } if (hr >= 0) { pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); // if this is the first clip, create the render graph if (m_Clips.Count == 1) { m_pRenderGraph = new FilterGraph() as IGraphBuilder; hr = m_pController.CreateRenderGraph(pClip.SinkFilter(), m_pRenderGraph, out m_pRenderGraphSourceFilter); if (hr >= 0 && m_hwndApp != IntPtr.Zero) { IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; if (pME != null) { pME.SetNotifyWindow(m_hwndApp, m_msgEvent, IntPtr.Zero); } } } } else { pClip.Dispose(); m_Clips.RemoveAt(it); } return hr; }
public ClipEntry(ClipEntry r) { m_tOffset = r.m_tOffset; m_pGraph = r.m_pGraph; m_pSinkFilter = r.m_pSinkFilter; m_strName = r.m_strName; m_tStart = r.m_tStart; m_tStop = r.m_tStop; m_bPrimed = r.m_bPrimed; }
public ClipEntry CurrentClip() { if (m_itCurrent == m_Clips.Count) { return(null); } ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; return(ce); }
ClipEntry Copy(ClipEntry r) { m_tOffset = r.m_tOffset; m_pGraph = r.m_pGraph; m_pSinkFilter = r.m_pSinkFilter; m_strName = r.m_strName; m_tStart = r.m_tStart; m_tStop = r.m_tStop; m_bPrimed = r.m_bPrimed; return(this); }
/// <summary> /// Unload audio clip from memory /// </summary> /// <param name="clipName">Name of audio clip</param> public void UnloadSound(string clipName) { if (lookupTable.ContainsKey(clipName)) { ClipEntry entry = clips[lookupTable[clipName]]; if (entry.loaded) { entry.loaded = false; entry.clip = null; } } }
/// <summary> /// Play audio clip once on certain position /// </summary> /// <param name="position">Position in world coordinates to play the audio clip</param> /// <param name="clipName">Name of audio clip</param> /// <param name="volume">Volume to play the audio</param> public void PlaySound(Vector3 position, string clipName, float volume = 1f) { if (lookupTable.ContainsKey(clipName)) { GameObject soundSource = new GameObject("Sound Source", typeof(AudioSource)); soundSource.transform.position = position; AudioSource source = soundSource.GetComponent <AudioSource>(); ClipEntry entry = clips[lookupTable[clipName]]; LoadSound(entry); source.clip = entry.clip; source.volume = volume; source.Play(); Destroy(soundSource, source.clip.length + 1f); } }
/// <summary> /// Load audio clip to memory /// </summary> /// <param name="clipName">Name of audio clip</param> public void LoadSound(string clipName) { if (lookupTable.ContainsKey(clipName)) { ClipEntry entry = clips[lookupTable[clipName]]; if (!entry.loaded) { entry.clip = Resources.Load <AudioClip>(entry.path); if (entry.clip != null) { entry.loaded = true; } } } }
private void bnLimits_Click(object sender, EventArgs e) { int idx = listBox1.SelectedIndex; ClipEntry pClip = null; if (idx != -1) { pClip = m_pPlayer.GetClipByIndex(idx); } if (pClip != null) { // duration, limits dlg -- set clip limits (in seconds) long lDur = ((pClip.NativeDuration() + UNITS - 1) / UNITS); long tStart, tStop; pClip.GetLimits(out tStart, out tStop); long lStart = ((tStart + UNITS - 1) / UNITS); long lStop = -1; if (tStop != 0) { lStop = ((tStop + UNITS - 1) / UNITS); } fmLimits dlg = new fmLimits((pClip.Duration() + UNITS - 1) / UNITS); dlg.tbStart.Text = lStart.ToString(); dlg.tbStop.Text = lStop.ToString(); if (dlg.ShowDialog() == DialogResult.OK) { long tStart2 = int.Parse(dlg.tbStart.Text) * UNITS; long tStop2 = pClip.NativeDuration(); if (int.Parse(dlg.tbStop.Text) > 0) { tStop2 = int.Parse(dlg.tbStop.Text) * UNITS; } m_pPlayer.SetClipLimits(pClip, tStart2, tStop2); string sDesc = string.Format("{0} [{1}..{2}]", pClip.Name(), tStart2 / UNITS, tStop2 / UNITS); int n = listBox1.SelectedIndex; listBox1.Items.RemoveAt(n); listBox1.Items.Insert(n, sDesc); } } }
public int SetClipLimits(ClipEntry pClip, long tStart, long tEnd) { long tDur = pClip.Duration(); int hr = pClip.SetLimits(tStart, tEnd); if (hr < 0 || (tDur == pClip.Duration())) { return(hr); } // this is called from the same message loop as the end-of-segment processing, so it's safe to // access the current segment if (pClip == CurrentClip()) { // send just the stop time to the graph // in the hope that it is not too late hr = pClip.SetStopTime(); } // clip duration has changed: update start position of // all subsequent clips (for current position slider UI) m_tDuration = 0; bool bFound = false; foreach (ClipEntry pThis in m_Clips) { if (pThis == pClip) { bFound = true; m_tDuration = pClip.GetStartPosition() + pClip.Duration(); } else if (bFound) { // following clip: adjust pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); } } return(S_OK); }
ClipEntry Copy(ClipEntry r) { m_tOffset = r.m_tOffset; m_pGraph = r.m_pGraph; m_pSinkFilter = r.m_pSinkFilter; m_strName = r.m_strName; m_tStart = r.m_tStart; m_tStop = r.m_tStop; m_bPrimed = r.m_bPrimed; return this; }
public void OnEndOfSegment() { if (m_itCurrent == m_Clips.Count) { // ? already at the end return; } int itOld = m_itCurrent; // locate next graph m_itCurrent++; if (m_pPlayNext >= 0) { // jump to specified clip m_itCurrent = m_pPlayNext; m_pPlayNext = -1; } if (m_itCurrent == m_Clips.Count) { if (!m_bLoop) { // no more clips, so allow EOS to propagate through // render graph. We will receive EC_COMPLETE eventually. m_pController.NoMoreSegments(); // disconnect graphs -- but we cannot do that until NoMoreSegments has // sent the EndOfStream through the bridge m_pController.BridgeGraphs(null, null); return; } // disconnect graphs before seeking the source graph m_pController.BridgeGraphs(null, null); m_itCurrent = 0; m_tStartPosition = 0; } ClipEntry ce = (ClipEntry)m_Clips[m_itCurrent]; // has this graph been rewound? ce.Prime(); // now we are about to connect it, so as soon as data is delivered out of the graph it // is no longer primed for re-use (it will need a new seek before using again) ce.InUse(); // reconnect m_pController.BridgeGraphs(ce.SinkFilter(), m_pRenderGraphSourceFilter); if (m_bLoop && (m_itCurrent != itOld)) { ce = (ClipEntry)m_Clips[itOld]; // need to rewind clip for next time round // unless we are reusing it immediately (ie looping single clip) // it's better to do this when not in use ce.Prime(0); } }
public int SetClipLimits(ClipEntry pClip, long tStart, long tEnd) { long tDur = pClip.Duration(); int hr = pClip.SetLimits(tStart, tEnd); if (hr < 0 || (tDur == pClip.Duration())) { return hr; } // this is called from the same message loop as the end-of-segment processing, so it's safe to // access the current segment if (pClip == CurrentClip()) { // send just the stop time to the graph // in the hope that it is not too late hr = pClip.SetStopTime(); } // clip duration has changed: update start position of // all subsequent clips (for current position slider UI) m_tDuration = 0; bool bFound = false; foreach (ClipEntry pThis in m_Clips) { if (pThis == pClip) { bFound = true; m_tDuration = pClip.GetStartPosition() + pClip.Duration(); } else if (bFound) { // following clip: adjust pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); } } return S_OK; }