ASP.NET’te FFMpeg ile Video Convert İşlemi

ASP.NET’te FFMpeg ile Video Convert İşlemi

Merhabalar,

Bir süre bir proje için uzun zaman harcadığım sonunda çözebildiğim video upload sorununa değinmek istiyorum.

Video ile ilgili herhangi bir şey yapacağınız zaman kesinlikle her yerde karşınıza FFMpeg çıkacaktır. Kullanışlı olduğu kadar çokta iyi hizmet vermesinden dolayı kendisine teşekkürü borç bilirim 🙂

Yalnız benim başımı ağrıtan husus aslında .NET’in cilvelerinden biriydi. Video upload işleminde boyut sorununu göz önüne alırsak, çalıştırdığımız process sonlansada arka tarafta sanki sonsuz döngüye girmiş gibi bekleyebiliyordu. Benim haricimde kaç kişinin başına geldi bu bilmiyorum ama ben pek doküman bulamadım o yüzden şimdi sorunun kaynağıyla birlikte örnek projeyi de paylaşacağım.

Sorun başlangıcı küçük boyutlu videoları sorunsuz convert edip, yüksek boyutlu videolarda processın kill olamamasıydı.

Normalde internette her yerde karşınıza çıkacak olan kod bloğu aşağıdaki gibidir.

public string convertFile(FileUpload fu, string outputextension, string arguments)
{
string input = string.Empty;
string output = string.Empty;
string result = string.Empty;
//yüklenen dosya
input = Server.MapPath("~/videos/input/") + fu.FileName;
//dönüştürülen dosya
output = Server.MapPath("~/videos/output/") + fu.FileName.Substring(0, fu.FileName.LastIndexOf('.')) + "." + outputextension;
//FFmpeg.exe'yi tetiklemek için Process kullanacağız.
Process convertProcess = new Process();
//FFmpeg.exe'ye gönderilecek parametre
convertProcess.StartInfo.Arguments = string.Format(arguments, input, output);
//FFmpeg.exe'nin dosya konumu
convertProcess.StartInfo.FileName = Server.MapPath("~/ref/ffmpeg.exe");
//FFmpeg.exe işlemi yaparken komut ekranını kapatıyoruz, çünkü hata durumunda oluşan hatayı alacak kodları aşağıda yazdık.
convertProcess.StartInfo.CreateNoWindow = true;
convertProcess.StartInfo.UseShellExecute = false;
convertProcess.StartInfo.RedirectStandardOutput = true;
convertProcess.StartInfo.RedirectStandardError = true;
convertProcess.Start();
StreamReader objStreamReader = convertProcess.StandardError;
StringBuilder sbOutPut = new StringBuilder();
convertProcess.WaitForExit();
sbOutPut.Append(objStreamReader.ReadToEnd().ToString());
//Hata yoksa boş değer döndürüyoruz.
if (convertProcess.ExitCode == 0)
{
convertProcess.Close();
if (objStreamReader != null)
{
objStreamReader.Close();
}
return result;
}
//Hata varsa hatayı döndürüyoruz.
else
{
convertProcess.Close();
result = sbOutPut.ToString();
if (objStreamReader != null)
objStreamReader.Close();
return result;
}

Bu kodlarda sorun yok çalışıyor fakat convertProcess.WaitForExit(); metodundan sonra işlem bir türlü devam etmiyor.
Benim yaptığım ise (yabancı bir kaynaktan 10 güne yakın bir zaman araştırma sonrasında buldum) kod bloğunu aşağıdaki şekilde düzenlemek oldu.

public string[] convertFile(FileUpload fu, string outputextension, string arguments)
{
string[] donder = new string[3];

//yüklenen dosya
fu.SaveAs(Server.MapPath("~/videos/input/") + fu.FileName);
donder[0] = "/videos/input/" + fu.FileName;
//dönüştürülen dosya
donder[1] = "/videos/output/" + fu.FileName.Substring(0, fu.FileName.LastIndexOf('.')) + "." + outputextension;
//FFmpeg.exe'yi tetiklemek için Process kullanacağız.
using (Process convertProcess = new Process())
{
//FFmpeg.exe'ye gönderilecek parametre
ProcessStartInfo p = new ProcessStartInfo();
//VideoConvertFile(dosya2, "mp4", "-y -i \"{0}\" -sameq -ar 22050 \"{1}\"");
convertProcess.StartInfo.Arguments = string.Format(arguments, Server.MapPath("~" + donder[0]), Server.MapPath("~" + donder[1]));
//FFmpeg.exe'nin dosya konumu
convertProcess.StartInfo.FileName = Server.MapPath("~/ffmpeg.exe");
//FFmpeg.exe işlemi yaparken komut ekranını kapatıyoruz, çünkü hata durumunda oluşan hatayı alacak kodları aşağıda yazdık.
convertProcess.StartInfo.CreateNoWindow = true;
convertProcess.StartInfo.UseShellExecute = false;
convertProcess.StartInfo.RedirectStandardOutput = true;
convertProcess.StartInfo.RedirectStandardError = true;
convertProcess.Start();
using (StreamReader sbOutPut = convertProcess.StandardError)
{
System.Text.StringBuilder output = new System.Text.StringBuilder();

using (StreamReader objStreamReader = convertProcess.StandardError)
{
while (!convertProcess.WaitForExit(1000))
{
output.Append(objStreamReader.ReadToEnd().ToString());
}

if (convertProcess.ExitCode == 0)
{
convertProcess.Close();
if (objStreamReader != null)
{
objStreamReader.Close();
}
}
else
{
convertProcess.Close();
donder[2] = output.ToString();
if (objStreamReader != null)
objStreamReader.Close();
}
return donder;
}
}
}
}

Konu ile alakalı projenin tüm source kodlarını paylaşıyorum. Umarım bir faydası dokunur.
Rar’ın şifresi yazilimcinotlari.com’dur. Linki: http://www.yazilimcinotlari.com/VideoConverter.rar
Not: Proje içerisinde HTML5 video playerda vardır fakat yapılandırmasını tamamlamadığımdan çalışmıyor.
Bol kodlu günler…

2,404 total views, 1 views today

2 Comments

murat

about 2 sene ago

Merhaba yazı için teşekkürler. Videodan resim alınca dik bir video ise resim 90 derece sola dönük gözüküyor. Yatay bir video ise 180 derece dönük gözüküyor. Neden olur acaba. Sizin projenizi indirdim öyle ordada.

Cevapla

Gani

about 2 sene ago

Merhabalar, Daha once karsima cikmadi ama tahminen soyluyorum bunu; video dik ise playerlar witdh ve height'ini kontrol ederek sanirim 90 derece saga ve sola ceviriyor olabilirler. Yuklediginiz videonun sizde olculerini alarak islem yaptirmaniz gerekebilir. Buna benzer bir kac kez resim isleme olaylarinda karsima cikmisti. Denemekte fayda vardir.

Cevapla

Leave a Comment

Ulaşım için: Facebook: /ganigani Twitter: @abdulgani_demir


*

%d blogcu bunu beğendi: