private long SeekForFlv(FlvFile flvFile, long seekToTime) { //시크 데이터와 2초 이상 차이가 생긴다면 시크 불가 상황으로 판단??? 영상의 끝은???? if (Math.Abs(seekToTime - flvFile.FlvFileBody.SeekData.FindSeekFrame(seekToTime).Key) > TimeSpan.FromSeconds(2).Ticks) { //시크 데이터 로딩중... flvFile.FlvFileBody.SeekData.Make(flvFile.Stream, seekToTime); } return(flvFile.FlvFileBody.SeekQueue(seekToTime)); }
private Task <Stream> ExtractAudio(Stream stream) { var flvFile = new FlvFile(stream); { flvFile.ConversionProgressChanged += (sender, args) => { AudioExtractionProgressChanged?.Invoke(this, args); }; return(flvFile.ExtractStreams()); } }
bool ValidateCodecForFlv(FlvFile flvFile) { ResourceLoader loader = ResourceLoader.GetForCurrentView(); DialogContent dc = new DialogContent(); if (flvFile.FlvHeader.Signature != "FLV") { CurrentMediaInfo.MediaType = MediaType.Unkown; dc.Content = string.Format(loader.GetString("WrongFileFormat"), "FLV"); dc.OccueredErrorMediaInfo = dc.Content; } if (flvFile.FlvFileBody.VideoInfoFlvTag.VideoData.CodecID != CodecID.AVC) { dc.Content = loader.GetString("NotSupportedVideoCodec"); dc.Description1 = flvFile.FlvFileBody.VideoInfoFlvTag.VideoData.CodecID.ToString(); dc.Description2 = string.Format(loader.GetString("NotSupportedCodecDesc"), "H264"); } if (flvFile.FlvFileBody.AudioInfoFlvTag.AudioData.SoundFormat != SoundFormat.AAC && flvFile.FlvFileBody.AudioInfoFlvTag.AudioData.SoundFormat != SoundFormat.MP3 && flvFile.FlvFileBody.AudioInfoFlvTag.AudioData.SoundFormat != SoundFormat.ADPCM) { dc.Content = loader.GetString("NotSupportedAudioCodec"); dc.Description1 = flvFile.FlvFileBody.AudioInfoFlvTag.AudioData.SoundFormat.ToString(); dc.Description2 = string.Format(loader.GetString("NotSupportedCodecDesc"), "AAC, MP3, PCM"); } if (!string.IsNullOrEmpty(dc.Content)) { //재생 종료 StopMedia(); //화면 닫기 if (IsPlayerOpened) { IsPlayerOpened = false; } //에러 메세지 처리 if (string.IsNullOrEmpty(dc.OccueredErrorMediaInfo)) { dc.OccueredErrorMediaInfo = ResourceLoader.GetForCurrentView().GetString("Message/Error/CodecNotSupported"); } //로딩 패널 숨김 HideLoadingBar(); //에러 메세지 ShowDialogMediaStreamSourceError(dc); return(false); } return(true); }
void PrepareSeekForFlv(FlvFile flvFile) { // seek data 로드 if (!flvFile.FlvFileBody.SeekData.IsScriptLoad) { var fsdDic = fileDAO.GetSeekingList(flvFile.Path); if (fsdDic != null) { flvFile.FlvFileBody.SeekData = new FlvSeekData(fsdDic); } //시크 이벤트 등록 flvFile.FlvFileBody.SeekData.ProgressStarted += SeekData_ProgressStarted; flvFile.FlvFileBody.SeekData.ProgressChanged += SeekData_ProgressChanged; flvFile.FlvFileBody.SeekData.ProgressCompleted += SeekData_ProgressCompleted; } }
async void OpenFlvFile(StorageFile file) { long offset = 0; FlvFile flvFile = null; var randomStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); mediaStreamFileSource = flvFile = new FlvFile(randomStream.AsStream(), ref offset) { Path = file.Path }; //에러 체크 (익셉션 발생) if (ValidateCodecForFlv(flvFile)) { //미디어 타입 설정 CurrentMediaInfo.MediaType = MediaType.FlashVideo; //H264 NalUnit Header 생성 SetNalUnitParameterSets(flvFile.FlvFileBody.VideoInfoFlvTag); //비디오/오디오 파일의 기술설명자 생성 IMediaStreamDescriptor videoDescriptor = GetFlvVideoDescriptor(flvFile.FlvFileBody.ScriptTageList); IMediaStreamDescriptor audioDescriptor = GetFlvAudioDescriptor(flvFile.FlvFileBody.AudioInfoFlvTag); //미디어 스트림 소스 생성 MediaStreamSource flvStreamSource = new MediaStreamSource(videoDescriptor, audioDescriptor); //기본 속성 설정 var value = flvFile.FlvFileBody.ScriptTageList.FirstOrDefault().ScriptData.Values[1].Value; flvStreamSource.Duration = TimeSpan.FromSeconds(double.Parse(((value as ScriptObject)["duration"]).ToString(), Settings.NumberFormat)); flvStreamSource.CanSeek = true; //이벤트 등록 flvStreamSource.VideoProperties.Title = CurrentMediaInfo.Title; flvStreamSource.Starting += flvStreamSource_Starting; flvStreamSource.SampleRequested += flvStreamSource_SampleRequested; flvStreamSource.Closed += flvStreamSource_Closed; //플레이어 기본 설정 및 스트림 전달 this.SetMediaStreamSource(flvStreamSource); //FVL 탐색용 데이터 준비 PrepareSeekForFlv(flvFile); } }
protected override void OpenMediaAsync() { var flvFile = new FlvFile(this.mediaStream); this.audioSamples = flvFile.FlvFileBody.Tags.Where(tag => tag.TagType == TagType.Audio).ToList(); this.videoSamples = flvFile.FlvFileBody.Tags.Where(tag => tag.TagType == TagType.Video).ToList(); //Audio WaveFormatExtensible wfx = new WaveFormatExtensible(); wfx.FormatTag = 0x00FF; wfx.Channels = 2; wfx.BlockAlign = 8; wfx.BitsPerSample = 16; wfx.SamplesPerSec = 44100; wfx.AverageBytesPerSecond = wfx.SamplesPerSec * wfx.Channels * wfx.BitsPerSample / wfx.BlockAlign; wfx.Size = 0; string codecPrivateData = wfx.ToHexString(); Dictionary <MediaStreamAttributeKeys, string> audioStreamAttributes = new Dictionary <MediaStreamAttributeKeys, string>(); audioStreamAttributes[MediaStreamAttributeKeys.CodecPrivateData] = codecPrivateData; this.audioStreamDescription = new MediaStreamDescription(MediaStreamType.Audio, audioStreamAttributes); //Video Dictionary <MediaStreamAttributeKeys, string> videoStreamAttributes = new Dictionary <MediaStreamAttributeKeys, string>(); videoStreamAttributes[MediaStreamAttributeKeys.VideoFourCC] = "H264"; this.videoStreamDescription = new MediaStreamDescription(MediaStreamType.Video, videoStreamAttributes); //Media Dictionary <MediaSourceAttributesKeys, string> mediaSourceAttributes = new Dictionary <MediaSourceAttributesKeys, string>(); mediaSourceAttributes[MediaSourceAttributesKeys.Duration] = audioSamples.Last().Timestamp.ToString(CultureInfo.InvariantCulture); mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] = true.ToString(); List <MediaStreamDescription> mediaStreamDescriptions = new List <MediaStreamDescription>(); mediaStreamDescriptions.Add(this.audioStreamDescription); mediaStreamDescriptions.Add(this.videoStreamDescription); this.ReportOpenMediaCompleted(mediaSourceAttributes, mediaStreamDescriptions); }
private async void button1_Click(object sender, EventArgs e) { //var videos = DownloadUrlResolver.GetDownloadUrls("https://www.youtube.com/watch?v=rTKHB_tVYpk"); //VideoInfo video = videos // .OrderByDescending(info => info.AudioBitrate) // .First(); //await Task.Factory.StartNew(() => //{ // var audioDownload = new AudioDownloader(video, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.mp3")); // audioDownload.DownloadProgressChanged += (s, args) => Console.WriteLine(args.ProgressPercentage * 0.85); // audioDownload.AudioExtractionProgressChanged += (s, args) => Console.WriteLine(85 + args.ProgressPercentage * 0.15); // audioDownload.Execute(); //}); string path = Path.Combine(@"D:\Recordings\Obs", "Haytam.flv"); FlvFile flvFile = new FlvFile(path, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.mp3")); flvFile.ConversionProgressChanged += (s, ea) => Console.WriteLine(ea.ProgressPercentage); flvFile.ExtractStreams(); flvFile.Dispose(); }
private void flvStreamSource_SampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args) { MediaStreamSourceSampleRequest request = args.Request; MediaStreamSourceSampleRequestDeferral deferal = request.GetDeferral(); FlvFile flvFile = mediaStreamFileSource as FlvFile; FlvTag flvTag = null; MemoryStream stream = null; MediaStreamSample sample = null; try { if (flvFile != null) { if (request.StreamDescriptor is VideoStreamDescriptor) { flvTag = flvFile.FlvFileBody.CurrentVideoTag; if (flvTag.VideoData.CodecID == CodecID.AVC) { byte[] by = flvTag.VideoData.AVCVideoPacket.NALUs; if (by != null && by.Length > 0) { MemoryStream srcStream = new MemoryStream(by); stream = new MemoryStream(); if (flvTag.VideoData.FrameType == FrameType.Keyframe) { if (NALUnitHeader != null) { stream.Write(NALUnitHeader, 0, NALUnitHeader.Length); } } using (BinaryReader reader = new BinaryReader(srcStream)) { var sampleSize = srcStream.Length; while (sampleSize > 4L) { var ui32 = reader.ReadUInt32(); var count = OldSkool.swaplong(ui32); stream.Write(h264StartCode, 0, h264StartCode.Length); stream.Write(reader.ReadBytes((int)count), 0, (int)count); sampleSize -= 4 + (uint)count; } } if (stream != null && stream.Length > 0) { IBuffer buffer = stream.ToArray().AsBuffer(); stream.Position = 0; sample = MediaStreamSample.CreateFromBuffer(buffer, TimeSpan.FromTicks(flvTag.Timestamp)); sample.KeyFrame = flvTag.VideoData.FrameType == FrameType.Keyframe; } } } else { IBuffer buffer = flvTag.VideoData.RawData.AsBuffer(); sample = MediaStreamSample.CreateFromBuffer(buffer, TimeSpan.FromTicks(flvTag.Timestamp)); sample.KeyFrame = flvTag.VideoData.FrameType == FrameType.Keyframe; } } else { byte[] by = null; flvTag = flvFile.FlvFileBody.CurrentAudioTag; switch (flvTag.AudioData.SoundFormat) { case SoundFormat.AAC: by = (flvTag.AudioData.SoundData as AACAudioData).RawAACFrameData; break; case SoundFormat.MP3: by = flvTag.AudioData.SoundData.RawData; break; case SoundFormat.ADPCM: by = flvTag.AudioData.SoundData.RawData; break; } if (by != null && by.Length > 0) { stream = new MemoryStream(by); IBuffer buffer = by.AsBuffer(); sample = MediaStreamSample.CreateFromBuffer(buffer, TimeSpan.FromTicks(flvTag.Timestamp)); sample.KeyFrame = true; request.Sample = sample; } } } //샘플보고 request.Sample = sample; } catch (Exception e) { System.Diagnostics.Debug.WriteLine("샘플오류 " + e.Message); sender.NotifyError(MediaStreamSourceErrorStatus.DecodeError); } finally { if (deferal != null) { deferal.Complete(); } } }
private Task SplitTaskDirectory(string inputVideoPath, string outputDirectoryPath, VideoConvertConfig config) { return(new Task(() => { var progress = 0; SetProgressBar(progress); var flvs = Util.GetAllFlvList(inputVideoPath); SetLabel4(flvs.Count); if (flvs.Count > 0) { var halfProgress = 50 / flvs.Count; using (var engine = new Engine()) { foreach (var flv in flvs) { var inputFile = new MediaFile(flv); var outputFile = new MediaFile(); if (config.OutputSameAsInput || string.IsNullOrWhiteSpace(outputDirectoryPath) || !Directory.Exists(outputDirectoryPath)) { outputDirectoryPath = Path.GetDirectoryName(flv); } var mp4File = new MediaFile(Path.Combine(outputDirectoryPath ?? throw new ArgumentNullException(nameof(outputDirectoryPath)), $@"{Path.GetFileNameWithoutExtension(flv)}.mp4")); //flv转封装成MP4 if (config.IsSkipSameMp4 && File.Exists(mp4File.Filename)) { //do nothing } else if (config.UseFlvFix) { using (var flvFile = new FlvFile(inputFile.Filename)) { flvFile.ExtractStreams(true, true, false, true); engine.CustomCommand(string.Format(MuxCommand, flvFile.VideoPath, flvFile.AudioPath, mp4File.Filename)); File.Delete(flvFile.VideoPath); File.Delete(flvFile.AudioPath); } } else { engine.CustomCommand(string.Format(ConvertCommand, inputFile.Filename, mp4File.Filename)); } progress += halfProgress; SetProgressBar(progress); if (!config.OnlyConvert) { //分段 if (Util.GetFileSize(mp4File.Filename) > Limit * 1024 / 8) { engine.GetMetadata(mp4File); var vb = mp4File.Metadata.VideoData.BitRateKbs ?? 0; var ab = mp4File.Metadata.AudioData.BitRateKbs; var maxDuration = TimeSpan.FromSeconds(Convert.ToDouble(Limit) / (vb + ab)); var duration = mp4File.Metadata.Duration; var now = TimeSpan.Zero; for (var i = 0; now < duration; ++i) { var t = Duration; if (now + maxDuration >= duration) { t = duration - now; } outputFile.Filename = Path.Combine(outputDirectoryPath, $@"{Path.GetFileNameWithoutExtension(mp4File.Filename)}_{i + 1}.mp4"); engine.CustomCommand(string.Format(SplitCommand, now, t, mp4File.Filename, outputFile.Filename)); engine.GetMetadata(outputFile); now += t; progress += Convert.ToInt32(Convert.ToDouble(now.Ticks) / duration.Ticks * halfProgress); SetProgressBar(progress); } } } else { progress += halfProgress; SetProgressBar(progress); } if (config.DeleteFlv && Util.IsFlv(inputFile.Filename)) { if (config.IsSendToRecycleBin) { FileSystem.DeleteFile(inputFile.Filename, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); } else { File.Delete(inputFile.Filename); } } } } } SetProgressBar(100); MessageBox.Show($@"{inputVideoPath} 完成!", @"提示", MessageBoxButtons.OK, MessageBoxIcon.Information); })); }
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { if (radioButton1.Checked == true) { if (!viddling.Contains("flv")) { label1.Text = "Status: Ready"; File.Copy(viddling, mp4out); File.Delete(viddling); } else { this.Cursor = Cursors.WaitCursor; ProcessStartInfo psi = new ProcessStartInfo(); string startdir = Directory.GetCurrentDirectory(); if (Environment.Is64BitOperatingSystem) { psi.FileName = ffmpeg + @"\Data\ffmpeg-64.exe"; } else { psi.FileName = ffmpeg + @"\Data\ffmpeg-32.exe"; } string convert = viddling; psi.Arguments = string.Format("-i \"{0}\" -y -sameq -ar 22050 \"{1}\"", viddling, mp4out); psi.WindowStyle = ProcessWindowStyle.Normal; Process p = Process.Start(psi); p.WaitForExit(); if (p.HasExited == true) { this.Cursor = Cursors.Default; File.Delete(viddling); } } } else if (radioButton2.Checked == true) { if (RipLeech.Properties.Settings.Default.ffmpeg == true) { this.Cursor = Cursors.WaitCursor; Process proc = new Process(); string convert = viddling; string bitrate = RipLeech.Properties.Settings.Default.audioquality; if (Environment.Is64BitOperatingSystem) { proc.StartInfo.FileName = ffmpeg + @"\Data\ffmpeg-64.exe"; } else { proc.StartInfo.FileName = ffmpeg + @"\Data\ffmpeg-32.exe"; } proc.StartInfo.Arguments = string.Format("-i \"{0}\" -vn -y -f mp3 -ab 320k \"{1}\"", viddling, vidout); proc.StartInfo.RedirectStandardError = true; proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.UseShellExecute = false; if (!proc.Start()) { listBox1.Items.Add("Error starting"); return; } StreamReader reader = proc.StandardError; string line; while ((line = reader.ReadLine()) != null) { listBox1.Items.Add(line); } proc.Close(); try { System.IO.StreamWriter sw = new System.IO.StreamWriter(Directory.GetCurrentDirectory() + @"\ffmpeg.log"); foreach (object item in listBox1.Items) { sw.WriteLine(item.ToString()); } sw.Close(); } catch { } button6.Visible = true; if (File.Exists(viddling)) { File.Delete(viddling); if (File.Exists(vidout)) { string mymusic = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic) + @"\" + vidname; //MessageBox.Show(mymusic); if (!String.IsNullOrEmpty(RipLeech.Properties.Settings.Default.audiosavepath)) { File.Copy(vidout, RipLeech.Properties.Settings.Default.audiosavepath + @"\" + vidname); } else { if (!File.Exists(mymusic)) { File.Copy(vidout, mymusic); } } File.Delete(vidout); } } this.Cursor = Cursors.Default; } else { //non ffmpeg functions var flvFile = new FlvFile(viddling, root + @"\" + vidname); flvFile.ExtractStreams(); if (File.Exists(viddling)) { File.Delete(viddling); if (File.Exists(vidout)) { string mymusic = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic) + @"\" + vidname; //MessageBox.Show(mymusic); if (!File.Exists(mymusic)) { File.Copy(vidout, mymusic); } File.Delete(vidout); } } } } else { } if (timer1.Enabled == true) { timer1.Stop(); timer1.Enabled = false; } label1.Text = "Status: Complete"; progressBar1.Value = 0; button4.Visible = true; button8.Visible = true; }