private static TrackMotionKeyframe GetOrCreateTrackMotionKeyframe(long timeFrame, VideoTrack selectedTrack) { TrackMotionKeyframe mkf = null; if (timeFrame == 0) { mkf = selectedTrack.TrackMotion.MotionKeyframes[0]; } else { mkf = selectedTrack.TrackMotion.InsertMotionKeyframe(Timecode.FromFrames(timeFrame)); } return(mkf); }
public void FromVegas(Vegas vegas) { int width = vegas.Project.Video.Width; int height = vegas.Project.Video.Height; int trackWidth = width / TracksX; int trackHeight = height / TracksY; int startX = -width / 2 + trackWidth / 2; int startY = height / 2 - trackHeight / 2; int trackIndex = 0; for (int y = 0; y < TracksY; y++) { for (int x = 0; x < TracksX; x++) { VideoTrack track = new VideoTrack(trackIndex++); vegas.Project.Tracks.Add(track); TrackMotionKeyframe mkf = track.TrackMotion.MotionKeyframes[0]; mkf.Width = trackWidth; mkf.Height = trackHeight; mkf.PositionX = startX + (x * trackWidth); mkf.PositionY = startY - (y * trackHeight); } } }
public void FromVegas(Vegas vegas) { // select a midi file MessageBox.Show("请选择一个MIDI文件。"); OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "*.mid|*.mid|所有文件|*.*"; openFileDialog.RestoreDirectory = true; openFileDialog.FilterIndex = 1; if (openFileDialog.ShowDialog() == DialogResult.OK) { midiName = openFileDialog.FileName; } else { return; } MidiFile midi = new MidiFile(midiName); // generate statistics of each midi track String[] trackInfo = new String[midi.Events.Tracks]; int ticksPerQuarter = midi.DeltaTicksPerQuarterNote; double msPerQuarter = 0; for (int i = 0; i < midi.Events.Tracks; i++) { String info1 = "轨道 " + i.ToString() + ": "; String info2 = ""; int notesCount = 0; String info3 = "起音 "; foreach (MidiEvent midiEvent in midi.Events[i]) { if ((midiEvent is NoteEvent) && !(midiEvent is NoteOnEvent)) { NoteEvent noteEvent = midiEvent as NoteEvent; if (notesCount == 0) { info3 = info3 + noteEvent.NoteName; } notesCount++; } if ((midiEvent is PatchChangeEvent) && info2.Length == 0) { PatchChangeEvent patchEvent = midiEvent as PatchChangeEvent; for (int j = 4; j < patchEvent.ToString().Split(' ').Length; j++) { info2 += patchEvent.ToString().Split(' ')[j]; } } if ((midiEvent is TempoEvent) && msPerQuarter == 0) { TempoEvent tempoEvent = midiEvent as TempoEvent; msPerQuarter = Convert.ToDouble(tempoEvent.MicrosecondsPerQuarterNote) / 1000; } } trackInfo[i] = info1 + info2 + "; 音符数: " + notesCount.ToString() + "; " + info3; } // select a video clip MessageBox.Show("请选择一个视频或图片素材片段。"); openFileDialog.Filter = "所有文件|*.*"; openFileDialog.RestoreDirectory = true; openFileDialog.FilterIndex = 1; if (openFileDialog.ShowDialog() == DialogResult.OK) { clipName = openFileDialog.FileName; } else { return; } Media media = new Media(clipName); double mediaLength = media.Length.ToMilliseconds(); // start configuration Form2 configForm = new Form2(); for (int i = 1; i < midi.Events.Tracks; i++) { configForm.comboBox1.Items.Add(trackInfo[i]); } configForm.comboBox1.SelectedIndex = 0; Application.Run(configForm); // apply condiguration for (int i = 1; i < midi.Events.Tracks; i++) { if (trackInfo[i] == configForm.comboBox1.SelectedItem.ToString()) { midiTrack = i; } } sheetWidth = int.Parse(configForm.width); sheetPosition = int.Parse(configForm.position); sheetGap = int.Parse(configForm.gap); if (configForm.comboBox2.Text == "2/4") { sheetTempo = 2; } if (configForm.comboBox2.Text == "3/4") { sheetTempo = 3; } if (configForm.comboBox3.Text == "低音") { sheetCelf = 1; } // start processing MIDI VideoTrack[] noteTracks = new VideoTrack[100]; int trackCount = -1; int trackPointer = 0; double barStartTime = 0; double barLength = msPerQuarter * sheetTempo; foreach (MidiEvent midiEvent in midi.Events[midiTrack]) { if (midiEvent is NoteOnEvent) { NoteEvent noteEvent = midiEvent as NoteEvent; NoteOnEvent noteOnEvent = midiEvent as NoteOnEvent; double startTime = midiEvent.AbsoluteTime * msPerQuarter / ticksPerQuarter; double duration = noteOnEvent.NoteLength * msPerQuarter / ticksPerQuarter; int pitch = noteEvent.NoteNumber; // next page while (startTime >= barStartTime + barLength) { barStartTime = barStartTime + barLength; trackPointer = 0; } // generate video events if (trackPointer > trackCount) { trackCount = trackCount + 1; noteTracks[trackCount] = vegas.Project.AddVideoTrack(); } VideoEvent videoEvent = noteTracks[trackPointer].AddVideoEvent(Timecode.FromMilliseconds(startTime), Timecode.FromMilliseconds(barStartTime + barLength - startTime)); Take take = videoEvent.AddTake(media.GetVideoStreamByIndex(0)); TrackEvent trackEvent = videoEvent as TrackEvent; trackEvent.Loop = true; TrackMotionKeyframe keyFrame = noteTracks[trackPointer].TrackMotion.InsertMotionKeyframe(Timecode.FromMilliseconds(startTime)); keyFrame.Type = VideoKeyframeType.Hold; keyFrame.Width = sheetGap * 2 * vegas.Project.Video.Width / vegas.Project.Video.Height; keyFrame.Height = sheetGap * 2; keyFrame.PositionX = -sheetWidth / 2 + sheetWidth / barLength * (startTime - barStartTime); int octave = pitch / 12; int line = pitchMap[pitch % 12]; keyFrame.PositionY = sheetPosition - sheetGap * 3 + (octave - 5) * sheetGap * 3.5 + line * sheetGap * 0.5 + sheetCelf * 12; trackPointer = trackPointer + 1; } } }
public void FromVegas(Vegas vegas) { // ---------------------------------------------------------------- // [1] スクリプト起動時に選択していたビデオトラックを取得 // ---------------------------------------------------------------- VideoTrack track = FindSelectedTrack(vegas.Project.Tracks); if (track == null) { return; } // ビデオトラックが無ければ中断 if (track == null) { MessageBox.Show("ビデオトラックを選択してください。"); return; } // ビデオトラックにトラックイベントが無ければ中断 TrackEvents events = track.Events; if (events.Count == 0) { MessageBox.Show("トラックにビデオが含まれていません。"); return; } // ---------------------------------------------------------------- // [2] 座標データを含むバイナリファイルを選択する // ---------------------------------------------------------------- OpenFileDialog ofd = new OpenFileDialog(); ofd.CheckFileExists = true; ofd.CheckPathExists = true; if (ofd.ShowDialog() != DialogResult.OK) { MessageBox.Show("読み込みを中止します。"); return; } // ---------------------------------------------------------------- // [3] 座標データ( long tick, float x, float y )を // を読み込むストリームを開く // ---------------------------------------------------------------- BinaryReader reader = new BinaryReader(File.OpenRead(ofd.FileName)); // 座標データ1つあたりのサイズ【座標データの形式によって変える】 const long dataPerRow = sizeof(long) + sizeof(float) + sizeof(float); // 座標データ数 long recordCount = reader.BaseStream.Length / dataPerRow; // ---------------------------------------------------------------- // [4] トラック内のトラックイベントがある期間のトラックモーションを読み込む // ---------------------------------------------------------------- // ビデオトラックのトラックモーションをクリアする track.TrackMotion.MotionKeyframes.Clear(); // 座標データの間引き【お好みで変える】 const long skipCount = 3; // 間引き数 long skip = 0; // 間引き数カウンタ // 最後のトラックイベントの情報 double farthestEnd = FindLastEventEnd(track); // 終了時刻[ms] // 直近のトラックイベントの情報 double nearestStart = 0; // 開始時刻[ms] double nearestEnd = 0; // 終了時刻[ms] // 座標データ数だけ以下を繰り返す for (long i = 0; i < recordCount; i++) { // 座標データの読み込み 【座標データの形式によって変える】 double nt = (double)(reader.ReadInt64() / 10000); // 時間変換(決め打ち: 1tick = 100ns から msに変換) double nx = 1920 * (reader.ReadSingle() - 0.5f); // 座標変換(決め打ち: [0,1]を[-960, 960]に変換) double ny = 1080 * (0.5f - reader.ReadSingle()); // 座標変換(決め打ち: [0,1]を[540,-540]に変換) // [4-A] 現在時刻ntが最後のトラックイベントの終了時刻を超えた時 if (nt > farthestEnd) { // 座標データを読み込む必要がないため、ループを抜ける。 break; } // [4-B] 現在時刻が、直近のトラックイベントの終了時刻を超えた時 if (nt > nearestEnd) { // 間引きカウンタリセット skip = 0; // 直近のトラックイベントの開始・終了時刻を更新する nearestStart = FindNearestEventStart(track, nt); nearestEnd = FindNearestEventEnd(track, nt); } // [4-C] 現在時刻ntが直近のトラックイベントの範囲内の時 if (nt >= nearestStart && nt <= nearestEnd) { // データを間引く skip--; if (skip <= 0) { skip = skipCount; // キーフレームを追加し、座標をセットする TrackMotionKeyframe frame = track.TrackMotion.InsertMotionKeyframe(new Timecode(nt)); frame.PositionX = nx; frame.PositionY = ny; } } } // [5] ストリームを閉じる reader.Close(); }