Полезные пункты контекстного меню для mp4 | ffmpeg
Цитата: Сергей от 02.09.2022, 14:57[spoiler title="Оффтоп"]Привет Хачатур🖐 Спасибо за рекомендации!
Про using я совсем не подумал😅Я правильно понимаю, что если написать так, то при первом обращении переменная запишет значение и больше не будет проверять файл:
string pathexe => File.Exists("ffmpeg.exe") ? th..А если так, то при каждом обращении будет проверка файла?
string pathexe() => File.Exists("ffmpeg.exe") ? th..
К сожалению, я ещё не прошёл Linq, но сокращение отличное, правда [simple_tooltip content='modified = new List<string> { "Заменить звук", "Извлечь wav", "Пересохранить mp4" }.All(x => (bool)key?.GetSubKeyNames().Any(y => y == x));']так[/simple_tooltip] работает только если все 3 ветки есть в реестре, если нету хотя бы одного из списка то modified не ставит значение true и удаляются пользовательские ключи. Пройду linq и буду смотреть как можно реализовать.[/spoiler]
Про using я совсем не подумал😅
Я правильно понимаю, что если написать так, то при первом обращении переменная запишет значение и больше не будет проверять файл:
string pathexe => File.Exists("ffmpeg.exe") ? th..
А если так, то при каждом обращении будет проверка файла?
string pathexe() => File.Exists("ffmpeg.exe") ? th..
К сожалению, я ещё не прошёл Linq, но сокращение отличное, правда [simple_tooltip content='modified = new List<string> { "Заменить звук", "Извлечь wav", "Пересохранить mp4" }.All(x => (bool)key?.GetSubKeyNames().Any(y => y == x));']так[/simple_tooltip] работает только если все 3 ветки есть в реестре, если нету хотя бы одного из списка то modified не ставит значение true и удаляются пользовательские ключи. Пройду linq и буду смотреть как можно реализовать.
Цитата: ЯR от 02.09.2022, 15:11Цитата: Mikhail от 02.09.2022, 14:37Привет, Михаил 🖐
Спасибо, исправил.
Чо-та много сегодня ошибок ... 😏
Цитата: Mikhail от 02.09.2022, 14:37
Привет, Михаил 🖐
Спасибо, исправил.
Чо-та много сегодня ошибок ... 😏
Цитата: XpucT от 02.09.2022, 16:13Сергей, в данном случае – это не играет роли. Важно то, что это не свойство, а не просто поле.
Прочти ещё раз, что написал про это. Роль играет именно то, что инициализироваться объект будет только при обращении.Цитата: Сергей от 02.09.2022, 14:57работает только если все 3 ветки есть в реестре, если нету хотя бы одного из списка то modified не ставит значение true
Совершенно верно.
А если требуется иначе, тогда Твой if не работает. Я писал с точки зрения логики того, что Ты пытался написать.
Если пытался другое – оно не работает по той же причине написанной опять же в предыдущем сообщении – все и всегда будут попадаться и в true и в false. Внимательно просмотри свой цикл или проверь его в Debug, чтобы посмотреть как много ненужных, а главное не дающих результата операций происходит.Опыт придёт с практикой. В будущем будешь строить LINQ запросы в уме =)
Сергей, в данном случае – это не играет роли. Важно то, что это не свойство, а не просто поле.
Прочти ещё раз, что написал про это. Роль играет именно то, что инициализироваться объект будет только при обращении.
Цитата: Сергей от 02.09.2022, 14:57работает только если все 3 ветки есть в реестре, если нету хотя бы одного из списка то modified не ставит значение true
Совершенно верно.
А если требуется иначе, тогда Твой if не работает. Я писал с точки зрения логики того, что Ты пытался написать.
Если пытался другое – оно не работает по той же причине написанной опять же в предыдущем сообщении – все и всегда будут попадаться и в true и в false. Внимательно просмотри свой цикл или проверь его в Debug, чтобы посмотреть как много ненужных, а главное не дающих результата операций происходит.
Опыт придёт с практикой. В будущем будешь строить LINQ запросы в уме =)
Цитата: XpucT от 02.09.2022, 16:21[spoiler title="Оффтоп:"]
Чтобы проще понимался код после просмотра урока по LINQ, предлагаю переписать на составные.
То есть, замени это:using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell")) modified = new List<string> { "Заменить звук", "Извлечь wav", "Пересохранить mp4" }.All(x => (bool)key?.GetSubKeyNames().Any(y => y == x));на это:
bool modified = false; using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell")) { List<string> paths = new List<string> { "Заменить звук", "Извлечь wav", "Пересохранить mp4" }; bool allExists = paths.All(path => (bool)key?.GetSubKeyNames().Any(gotPath => gotPath == path)); if (allExists == true) modified = true; }Тем не менее, Я что по-русски, что по-сишарповски выражаюсь кратко и точно, поэтому, если переменная никогда не требуется, Я не объявляю её. То же касается списка слов. Если он нужен только в одном месте, Я напишу всю логику в одну строку и по-Мне лично – это более читабельно и понятно, чем 100 строк, 100 классов, 100 переменных. Тут главное не дойти до фанатизма и не сокращать из принципа.
[/spoiler]
Чтобы проще понимался код после просмотра урока по LINQ, предлагаю переписать на составные.
То есть, замени это:
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell"))
modified = new List<string> { "Заменить звук", "Извлечь wav", "Пересохранить mp4" }.All(x => (bool)key?.GetSubKeyNames().Any(y => y == x));
на это:
bool modified = false;
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell"))
{
List<string> paths = new List<string>
{
"Заменить звук",
"Извлечь wav",
"Пересохранить mp4"
};
bool allExists = paths.All(path => (bool)key?.GetSubKeyNames().Any(gotPath => gotPath == path));
if (allExists == true)
modified = true;
}
Тем не менее, Я что по-русски, что по-сишарповски выражаюсь кратко и точно, поэтому, если переменная никогда не требуется, Я не объявляю её. То же касается списка слов. Если он нужен только в одном месте, Я напишу всю логику в одну строку и по-Мне лично – это более читабельно и понятно, чем 100 строк, 100 классов, 100 переменных. Тут главное не дойти до фанатизма и не сокращать из принципа.
Цитата: Mikhail от 02.09.2022, 17:32Цитата: kokos от 02.09.2022, 12:54Добрый день. есть просьба. было бы здорово сделать такой же шелл для качественного пережатия из мп4 в гиф. если конечно это возможно. заранее спасибо
Перепробовал кучу вариантов, но Gif весит больше чем видео в 10-20 раз), даже если палитру создавать, все равно не выходит маленький размер(или я не нашел как правильно), если в 5-10fps сохранять, тогда что-то получается, но это не серьезно, поэтому пользуемся, ScreenToGif.
Цитата: kokos от 02.09.2022, 12:54Добрый день. есть просьба. было бы здорово сделать такой же шелл для качественного пережатия из мп4 в гиф. если конечно это возможно. заранее спасибо
Перепробовал кучу вариантов, но Gif весит больше чем видео в 10-20 раз), даже если палитру создавать, все равно не выходит маленький размер(или я не нашел как правильно), если в 5-10fps сохранять, тогда что-то получается, но это не серьезно, поэтому пользуемся, ScreenToGif.
Цитата: XpucT от 02.09.2022, 18:28Привет, Миш 🖐
Чуть позже займусь. Помню точно, что делал и делал это с прекрасным результатом. То есть нужно искать =)
Тот же ScreenToGif даёт наилучший результат именно в купе с ffmpeg.
Привет, Миш 🖐
Чуть позже займусь. Помню точно, что делал и делал это с прекрасным результатом. То есть нужно искать =)
Тот же ScreenToGif даёт наилучший результат именно в купе с ffmpeg.
Цитата: Jeddi Rodnulkin от 02.09.2022, 19:14привет, респект, полезно
привет, респект, полезно
Цитата: Андрей от 02.09.2022, 20:02Всем доброго часа!
Присоединяюсь, очень полезные опции (за первый день уже сэкономили мне кучу времени, особенно выручает на ноутбуке, где нет особого желания запускать видеоредакторы без острой на то необходимости). Ну и пережимает просто класс.[spoiler title="Оффтоп"]Возник вопрос не по теме, но касающийся того, что здесь обсуждалось. Речь о LINQ-сокращении проверки. Поясните, пожалуйста, в чём мой затуп. Изначально в коде был цикл:
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell", false)) if (key != null) foreach (string name in key.GetSubKeyNames()) if (name != "Заменить звук" && name != "Извлечь wav" && name != "Пересохранить mp4") modified = true;Согласно которому, если в ветке реестра
SOFTWARE\Classes\SystemFileAssociations\.mp4\shellокажется любой ключ, не имеющий названия из if'а - то modified станет true, и вместо удаления ветки - произойдёт точечное удаление ключей, созданных программой. При этом не важно, сколько ключей из этого if'а будет в ветке (могут быть все 3, а может и ни одного - на результаты проверки это не влияет).Хачатур же предложил заменить это сперва на
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell")) modified = (bool)key?.GetSubKeyNames().All(x => x != "Заменить звук" && x != "Извлечь wav" && x != "Пересохранить mp4");Где modified становится true только в случае, если в папке нет ни одного ключа указанного в условии. И в следующем примере:
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell")) modified = new List<string> { "Заменить звук", "Извлечь wav", "Пересохранить mp4" }.All(x => (bool)key?.GetSubKeyNames().Any(y => y == x));modified будет true только если в ней есть все 3 ключа из списка, но могут быть и другие ключи (на true это не отразится).
Правильно ли я понял условия true, и если да - то в чём смысл таких проверок и как их далее грамотно применять? Ведь изначальная цель, как я понял - установить, есть ли в веткеshellсторонние ключи (помимо «Заменить звук», «Извлечь wav» и «Пересохранить mp4»).[/spoiler]
Всем доброго часа!
Присоединяюсь, очень полезные опции (за первый день уже сэкономили мне кучу времени, особенно выручает на ноутбуке, где нет особого желания запускать видеоредакторы без острой на то необходимости). Ну и пережимает просто класс.
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell", false))
if (key != null)
foreach (string name in key.GetSubKeyNames())
if (name != "Заменить звук" && name != "Извлечь wav" && name != "Пересохранить mp4")
modified = true;
Согласно которому, если в ветке реестра СкопированоSOFTWARE\Classes\SystemFileAssociations\.mp4\shell окажется любой ключ, не имеющий названия из if'а - то modified станет true, и вместо удаления ветки - произойдёт точечное удаление ключей, созданных программой. При этом не важно, сколько ключей из этого if'а будет в ветке (могут быть все 3, а может и ни одного - на результаты проверки это не влияет).
Хачатур же предложил заменить это сперва на
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell"))
modified = (bool)key?.GetSubKeyNames().All(x => x != "Заменить звук" && x != "Извлечь wav" && x != "Пересохранить mp4");
Где modified становится true только в случае, если в папке нет ни одного ключа указанного в условии. И в следующем примере:
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell"))
modified = new List<string> { "Заменить звук", "Извлечь wav", "Пересохранить mp4" }.All(x => (bool)key?.GetSubKeyNames().Any(y => y == x));
modified будет true только если в ней есть все 3 ключа из списка, но могут быть и другие ключи (на true это не отразится).
Правильно ли я понял условия true, и если да - то в чём смысл таких проверок и как их далее грамотно применять? Ведь изначальная цель, как я понял - установить, есть ли в ветке Скопированоshell сторонние ключи (помимо «Заменить звук», «Извлечь wav» и «Пересохранить mp4»).
Цитата: timser от 02.09.2022, 20:49Приветствую!
Вами были добавлены слева 3 чекбокса, значит создание пунктов (разделов) в реестре должно быть согласно выставленным галочкам.
Вам Хачатур давал ранее код для записи этих пунктов в реестр, там немного надо изменить, а то могут быть ошибки, если нет ещё раздела .mp4.
[spoiler title=""]using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations", true)) { if (checkBox1.Checked) { key.CreateSubKey(@".mp4\shell\Заменить звук").SetValue("icon", $"\"{pathicon}\""); key.CreateSubKey(@".mp4\shell\Заменить звук\command").SetValue("", $"\"{pathexe}\" -i \"%1\" -i 1.mp3 -c:v copy -map 0:v:0 -map 1:a:0 \"%1.mp4\""); checkBox1.Checked = false; } if (checkBox2.Checked) { key.CreateSubKey(@".mp4\shell\Извлечь wav").SetValue("icon", $"\"{pathicon}\""); key.CreateSubKey(@".mp4\shell\Извлечь wav\command").SetValue("", $"\"{pathexe}\" -i \"%1\" \"%1.wav\""); checkBox2.Checked = false; } if (checkBox3.Checked) { key.CreateSubKey(@".mp4\shell\Пересохранить mp4").SetValue("icon", $"\"{pathicon}\""); if (!CheckBoxAlt.Checked) key.CreateSubKey(@".mp4\shell\Пересохранить mp4\command").SetValue("", $"\"{pathexe}\" -i \"%1\" -crf 22 \"%1.mp4\""); else key.CreateSubKey(@".mp4\shell\Пересохранить mp4\command").SetValue("", $"\"{pathexe}\" -i \"%1\" -c:v h264_nvenc -preset llhq -rc constqp -qp 21 -c:a copy \"%1.mp4\""); checkBox3.Checked = false; } }[/spoiler]
А насчёт удаления, то тоже надо создать условие на проверку выставленных галочек, может надо не всё удалять, а только какой-то пункт.
Помимо этого должно быть условие на проверку других пунктов, и если есть, то удалять только пункты (разделы), но только те, которые слева помечены.
Если нет других, то можно удалять полностью раздел .mp4, но только если выделены все чекбоксы, иначе удалять только конкретные выделенные.
Приветствую!
Вами были добавлены слева 3 чекбокса, значит создание пунктов (разделов) в реестре должно быть согласно выставленным галочкам.
Вам Хачатур давал ранее код для записи этих пунктов в реестр, там немного надо изменить, а то могут быть ошибки, если нет ещё раздела .mp4.
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations", true))
{
if (checkBox1.Checked)
{
key.CreateSubKey(@".mp4\shell\Заменить звук").SetValue("icon", $"\"{pathicon}\"");
key.CreateSubKey(@".mp4\shell\Заменить звук\command").SetValue("", $"\"{pathexe}\" -i \"%1\" -i 1.mp3 -c:v copy -map 0:v:0 -map 1:a:0 \"%1.mp4\"");
checkBox1.Checked = false;
}
if (checkBox2.Checked)
{
key.CreateSubKey(@".mp4\shell\Извлечь wav").SetValue("icon", $"\"{pathicon}\"");
key.CreateSubKey(@".mp4\shell\Извлечь wav\command").SetValue("", $"\"{pathexe}\" -i \"%1\" \"%1.wav\"");
checkBox2.Checked = false;
}
if (checkBox3.Checked)
{
key.CreateSubKey(@".mp4\shell\Пересохранить mp4").SetValue("icon", $"\"{pathicon}\"");
if (!CheckBoxAlt.Checked)
key.CreateSubKey(@".mp4\shell\Пересохранить mp4\command").SetValue("", $"\"{pathexe}\" -i \"%1\" -crf 22 \"%1.mp4\"");
else
key.CreateSubKey(@".mp4\shell\Пересохранить mp4\command").SetValue("", $"\"{pathexe}\" -i \"%1\" -c:v h264_nvenc -preset llhq -rc constqp -qp 21 -c:a copy \"%1.mp4\"");
checkBox3.Checked = false;
}
}
А насчёт удаления, то тоже надо создать условие на проверку выставленных галочек, может надо не всё удалять, а только какой-то пункт.
Помимо этого должно быть условие на проверку других пунктов, и если есть, то удалять только пункты (разделы), но только те, которые слева помечены.
Если нет других, то можно удалять полностью раздел .mp4, но только если выделены все чекбоксы, иначе удалять только конкретные выделенные.
Цитата: Андрей от 02.09.2022, 21:04Привет! Я так понял, ты не совсем в курсе: Хачатур этот код привёл в качестве рефакторинга исходника Сергея. Он так же говорил, что тот код с галочками в его варианте (через using) должен работать на любой системе и в любом случае без ошибок, хотя у меня тоже до сноса ветки .mp4 под if'ы - возникала ошибка. Пока не разобрался как её избежать, и чтобы в using'е сразу был OpenSubKey
SOFTWARE\Classes\SystemFileAssociations\.mp4. Так что вопрос касается именно реализации этих поправок в исходнике Сергея.
Привет! Я так понял, ты не совсем в курсе: Хачатур этот код привёл в качестве рефакторинга исходника Сергея. Он так же говорил, что тот код с галочками в его варианте (через using) должен работать на любой системе и в любом случае без ошибок, хотя у меня тоже до сноса ветки .mp4 под if'ы - возникала ошибка. Пока не разобрался как её избежать, и чтобы в using'е сразу был OpenSubKey СкопированоSOFTWARE\Classes\SystemFileAssociations\.mp4. Так что вопрос касается именно реализации этих поправок в исходнике Сергея.
Цитата: XpucT от 02.09.2022, 21:39Я только сейчас понял, спасибо timser о чём сказал Андрей.
Я думал речь вообще про эту строку:
using (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell")), где не имеет смысла ставить false, т.к. это параметр по умолчанию и в принципе мы там ничего не пишем, а читаем. Речь о другом. Прошу прощения у Андрея, т.к. не так понял поправку.И да, нужно Open заменить на Create.
А ещё лучше вообще переписать =)
Я только сейчас понял, спасибо timser о чём сказал Андрей.
Я думал речь вообще про эту строку:
Скопированоusing (var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\SystemFileAssociations\.mp4\shell"Скопировано)), где не имеет смысла ставить false, т.к. это параметр по умолчанию и в принципе мы там ничего не пишем, а читаем. Речь о другом. Прошу прощения у Андрея, т.к. не так понял поправку.
И да, нужно Open заменить на Create.
А ещё лучше вообще переписать =)
Цитата: XpucT от 03.09.2022, 02:01Обновил пост, добавил GIF. Скажите спасибо Mikhail.
Если бы не Миша, Я бы не парился, ибо оказалось, что задачка-не из лёгких =)
Обновил пост, добавил GIF. Скажите спасибо Mikhail.
Если бы не Миша, Я бы не парился, ибо оказалось, что задачка-не из лёгких =)
Цитата: XpucT от 03.09.2022, 02:38Цитата: shim от 02.09.2022, 10:49Добрый день!
можно добавить пункт "отключение звука в видео" или "пересохранить без аудио" ?Привет 🖐
Держи.
Цитата: shim от 02.09.2022, 10:49Добрый день!
можно добавить пункт "отключение звука в видео" или "пересохранить без аудио" ?
Привет 🖐
Держи.
Цитата: Mikhail от 03.09.2022, 03:01Цитата: XpucT от 03.09.2022, 02:01Обновил пост, добавил GIF. Скажите спасибо Mikhail.
Если бы не Миша, Я бы не парился, ибо оказалось, что задачка-не из лёгких =)Привет.
Все равно размер конский😅, у меня что-то похожее получалось.
Ролик 13 секундный.
[spoiler title="Скриншот"]
[/spoiler]
Цитата: XpucT от 03.09.2022, 02:01Обновил пост, добавил GIF. Скажите спасибо Mikhail.
Если бы не Миша, Я бы не парился, ибо оказалось, что задачка-не из лёгких =)
Привет.
Все равно размер конский😅, у меня что-то похожее получалось.
Ролик 13 секундный.
