Создание эскизов из нескольких видео на рабочем столе, используя ffmpeg или что-то подобное - PullRequest
0 голосов
/ 30 ноября 2010

Привет, ребята, это длинный выстрел, но здесь идет ...

У меня в основном то, что я упомянул в названии, работающем на моем сервере.Когда я загружаю видео, ffmpeg распаковывает его и дает мне скриншоты, затем я выбираю скриншот, который хочу использовать для этого видео.В настоящее время мой сервер может обрабатывать 3 видео одновременно.Недостатком является то, что это потребляет МНОГО вычислительной мощности сервера.: (

Есть ли способ или программа, которая может обрабатывать несколько видео одновременно и генерировать мне скриншоты на моем рабочем столе? Если это возможно, тогда я могу просто использовать свой запасной компьютер, чтобы обработать все, тогдазагрузите скриншоты / видео на мой сервер.

Это то, что я сейчас использую на сервере. kayweb.com.au / blogs / Web-Development / Generation-screenshots-using-FFmpeg

Примерно так, но этот генератор миниатюр помещает все в одно изображение. Мне нужно иметь возможность выбирать с миниатюрой, которую я хочу использовать. http://www.tothepc.com/archives/make-movie-caps-screenshots-with-free-video-thumbnails-maker/

У кого-нибудь есть предложения?

1 Ответ

0 голосов
/ 20 марта 2011

Проблема с получением нескольких больших пальцев - это время.До сих пор я не смог получить несколько больших пальцев за одно сканирование, так что это означает, что мне нужно сканировать три раза для трех изображений.

В моем случае я взял видео в считанные секунды, а затем получил триизображения от 1/4, 1/2 и 3/4.Но для длинных видео это слишком медленно, даже используя значение смещения ffmpeg.Лучше, если вы сможете выбрать из первых 10-20 секунд видео.

Так что я начну с предварительной обработки, при которой изображения сканируются во время поиска файла, а затем все, что имело место.Если создать большой палец, он создает одну из нескольких секунд в видео, что является быстрым процессом и в собственной цепочке не очень заметен, если не много видео, нуждающихся в значке, поэтому первый запуск будетбудь медленным.

Тогда, как и в форме функций, если большой палец не годится, я разрешаю выбор из моих 3 больших пальцев, которые генерируются на лету.В моем случае я использовал MDI, чтобы я мог жениться на разных частях медиа-пакета.Таким образом, часть ниже представляет собой отдельную форму, список файлов «videoList», который был заполнен, когда пользователь выбрал каталог в другой форме.

Просто для полноты я включу мои перечисления MediaItem и MediaType.

Не обращайте внимания на то, как я назвал свои временные файлы, я все еще работаю над этим, потому что позже я выйду за него со службой, которая предоставит имя.Вы можете столкнуться с проблемами при использовании тех же файлов в C #, которые были только что созданы или изменены во внешнем процессе, поэтому вам нужно некоторое умное соглашение об использовании файлов.

    public partial class ThumbSelector : Form
{
    public List<MediaItem> videoList = new List<MediaItem>();
    private Random ra = new Random();
    int iCount = 1;

    public ThumbSelector()
    {
        InitializeComponent();
    }

    public void FillList()
    {
        if(videoList.Count() < 1)
            return;
        //only get mp4 files
        var videosOnly = from n in videoList
                      where n.mainType == MediaMainType.MMT_VIDEO
                      select n;
        lbVideoList.Items.Clear();
        foreach (MediaItem mi in videosOnly)
        {
            lbVideoList.Items.Add(mi.shortName);
        }
    }

    private void lbVideoList_SelectedIndexChanged(object sender, EventArgs e)
    {
        if(lbVideoList.SelectedItems.Count < 1)
            return;
        CreateThumbs(lbVideoList.SelectedItems[0].ToString());
    }

    private void CreateThumbs(string fShortName)
    {
        string sourceVideoName;
        int sourceLength = 0;
        int quarter = 0;
        int half = 0;
        int threequarter = 0;
        string destDir = @"C:\Users\robert\dwhelper\VideoIcons";

        string ffPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";

        var sname = (from n in videoList
                    where n.shortName == fShortName
                     select n).First();
        sourceVideoName = sname.fullName;
        sourceLength = GetVideoLength(ffPath, sourceVideoName);

        quarter = sourceLength / 4;
        half = sourceLength / 2;
        threequarter = quarter * 3;
        Image im1;
        Image im2;
        Image im3;
        string n1;
        string n2;
        string n3;


        while (File.Exists(string.Concat(destDir, @"\", "x1_", iCount.ToString(), ".jpg")))
        {
            ++iCount;
        }
        n1 = string.Concat("x1_", iCount.ToString(), ".jpg");
        ++iCount;
        while (File.Exists(string.Concat(destDir, @"\", "x2_", iCount.ToString(), ".jpg")))
        {
            ++iCount;
        }
        n2 = string.Concat("x2_", iCount.ToString(), ".jpg");
        ++iCount;
        while (File.Exists(string.Concat(destDir, @"\", "x3_", iCount.ToString(), ".jpg")))
        {
            ++iCount;
        }
        n3 = string.Concat("x3_", iCount.ToString(), ".jpg");

        pic1.Image = null;
        pic2.Image = null;
        pic3.Image = null;


        CreateThumbs(sname, quarter, n1);
        im1 = Image.FromFile(string.Concat(destDir, @"\", n1));
        pic1.Image = im1;
        CreateThumbs(sname, half, n2);
        im2 = Image.FromFile(string.Concat(destDir, @"\", n2));
        pic2.Image = im2;
        CreateThumbs(sname, threequarter, n3);
        im3 = Image.FromFile(string.Concat(destDir, @"\", n3));
        pic3.Image = im3;

    }

    private void CreateThumbs(MediaItem mi, int timeIn, string outName)
    {
        this.Cursor = Cursors.WaitCursor;
        Process pth;
        string destDir = @"C:\Users\robert\dwhelper\VideoIcons";
        string sourceFile;
        string destFile;
        string ffPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";
        string strCommand;
        string fullCommand;
        string[] ssplit;

        sourceFile = mi.fullName;
        ssplit = mi.shortName.Split('.');
        destFile = string.Concat(destDir, "\\", outName);

        strCommand = string.Concat(
            " -i \"", sourceFile, "\" -r 1 -ss ", timeIn.ToString(), " -t 00:00:01 -f image2 \"", destFile, "\"");

        fullCommand = string.Concat(ffPath, strCommand);

        pth = new Process();
        pth.StartInfo.FileName = ffPath;
        pth.StartInfo.Arguments = strCommand;
        pth.StartInfo.UseShellExecute = false;
        pth.StartInfo.CreateNoWindow = true;

        pth.Start();
        pth.WaitForExit();

        this.Cursor = Cursors.Default;

    }

    private int GetVideoLength(string ffmpeg, string sourceFile)
    {
        //exec('start C:\Inetpub\ffmpeg\ffmpeg -i "D:/Jaime-flex.wmv" 2>&1 | grep "Duration" | cut -d " " -f 4 - | sed s/,//', $output);
        string result = "";
        string strCommand = string.Concat(
                " -i \"", sourceFile, "\" 2>");
        Process pth = new Process();
        pth.StartInfo.FileName = ffmpeg;
        pth.StartInfo.Arguments = strCommand;
        pth.StartInfo.UseShellExecute = false;
        pth.StartInfo.CreateNoWindow = true;
        pth.StartInfo.RedirectStandardOutput = true;
        pth.StartInfo.RedirectStandardError = true;
        pth.Start();


        pth.WaitForExit();
        //result = pth.StandardOutput.ReadToEnd();
        //result = pth.StandardError.ReadToEnd();
        string str = "";
        string[] ssplit;
        char[] splitChars = new char[] { '.', ' ' };
        int seconds = 0;
        while (!pth.StandardError.EndOfStream)
        {
            str = pth.StandardError.ReadLine();
            if (str.Contains("Duration"))
            {
                ssplit = str.Split(splitChars);
                seconds = GetSeconds(ssplit[3]);
            }
        }
        return seconds;
    }

    private int GetSeconds(string p)
    {
        string[] ssplit = p.Split(':');
        int ho = Convert.ToInt32(ssplit[0]) * 120;
        int mi = Convert.ToInt32(ssplit[1]) * 60;
        int se = Convert.ToInt32(ssplit[2]);

        return ho + mi + se;
    }

}
public class MediaItem
{
    public string shortName { get; set; }
    public string fullName { get; set; }
    public string iconName { get; set; }
    public MediaMainType mainType { get; set; }
    public MediaSubType subType { get; set; }
    public long length { get; set; }
}
public enum MediaMainType
{
    MMT_VIDEO = 0, MMT_IMAGE, MMT_ICON, MMT_NOTMEDIA
}
public enum MediaSubType
{
    MST_JPG = 0, MST_GIF, MST_BMP, MST_PNG, MST_MP4, MST_WMV, MST_FLV, MST_NOTMEDIA
3
...