<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; CMD/BAT: (+JS) Демонстрация приёмов обработки текста, скачивание видео]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=18616</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=18616&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «CMD/BAT: (+JS) Демонстрация приёмов обработки текста, скачивание видео».]]></description>
		<lastBuildDate>Mon, 03 Aug 2026 07:50:27 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[CMD/BAT: (+JS) Демонстрация приёмов обработки текста, скачивание видео]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=163475#p163475</link>
			<description><![CDATA[<p>Писал уже на Хабре, скрипт обновляется периодически на GitHub, но как-то забыл опубликовать здесь - всё таки много полезного узнал в своё время на script-coding[.]info ещё, да и гибридные скрипты впервые здесь увидел. Задача в чём: нужно как можно быстрее скачать в нужном мне качестве видео посредством yt-dlp, проблема ещё в том, что с некоторых сайтов после редизайна стандартно не скачивает вообще. В общем нормальный батник, только &quot;продвинутая&quot; обработка текста передаётся js части скрипта, между ним и cmd частью организовано взаимодействие. Просто иллюстрация некоторых приёмов. Возможно, кому-то покажется интересным. Вот текущая версия скрипта:<br /></p><div class="codebox"><pre><code>
@set @x=0 /*
@echo off
chcp 65001 &gt;nul
setlocal
set VideoURL=https://smotrim.ru/brand/67607#playing_video=2627918
set head=
set suffix=
set series=%%(series)s. 
call :set_template
set format=b
set enable_format_recommendations=1
set extension=mkv
set AppPath=D:\kvk\Utilities\GitHub\yt-dlp\yt-dlp.cmd
if not exist %AppPath% set AppPath=yt-dlp.exe
if not -%1- == -- (set format=%1 &amp; set enable_format_recommendations=0)
set tempFileName=%random%.tmp
call %AppPath% -o &quot;%%template:.!=%%&quot; --windows-filenames --socket-timeout 45 --print-to-file filename %%tempFileName%% --skip-download %%VideoURL%%
if not errorlevel 0 if exist %tempFileName% del /q %tempFileName%
if exist %tempFileName% goto :normal_process
:: после редизайна сайта smotrim.ru
for /f &quot;tokens=1,2,3,4 delims=,&quot; %%i in (&#039;cscript /nologo /e:javascript &quot;%~dpnx0&quot; %tempFileName% /GetSmotrimData:&quot;%VideoURL%&quot;&#039;) do if not &quot;%%i&quot; == &quot;&quot; set new_url=&quot;%%i&quot;&amp;set id=%%j&amp;set json_url=%%k&amp;set duration=%%l
if not defined new_url exit /b
set /p title=&lt;%tempFileName%
set template=%head%%title% [+%id%]%suffix%.%extension%
if exist %tempFileName% del /q %tempFileName%
set filename=&quot;%template%.txt&quot;
echo %VideoURL% &gt; %filename%
echo. &gt;&gt; %filename%
echo %json_url% &gt;&gt; %filename%
echo %new_url% &gt;&gt; %filename%
set VideoURL=%new_url%
echo. &gt;&gt; %filename%
call %AppPath% --socket-timeout 45 --print formats_table %VideoURL% &gt;&gt; %filename%
cscript /nologo /e:javascript &quot;%~dpnx0&quot; %filename%
if -%1- == ---- exit /b
start &quot;yt-dlp: smotrim&quot; %AppPath% -k -o &quot;%template%&quot; --replace-in-metadata &quot;title&quot; &quot;playlist&quot; &quot;%title%&quot; --windows-filenames --remux-video %extension% --concurrent-fragments 10 --socket-timeout 45 --abort-on-unavailable-fragment --exec &quot;pause &quot; --embed-metadata --postprocessor-args &quot;Metadata+ffmpeg:-metadata duration_string=%duration%&quot; --format %format% %VideoURL%^&amp;exit/b
exit /b
:normal_process
cscript /nologo /e:javascript &quot;%~dpnx0&quot; %tempFileName%
set /p filename=&lt;%tempFileName%
set processed_series=%filename:!.=!%
if not &quot;%processed_series%&quot; == &quot;%filename%&quot; (setlocal enabledelayedexpansion &amp; set series=!series:~0,-2! &amp; setlocal disabledelayedexpansion &amp; call :set_template &amp; set filename=%processed_series%)
set filename_without_series=%filename:NA. =%
if not &quot;%filename_without_series%&quot; == &quot;%filename%&quot; (set series=&amp; call :set_template &amp; set filename=%filename_without_series%)
setlocal enabledelayedexpansion
set filename=!filename:.mp4=.%extension%!
set filename=!filename:.webm=.%extension%!.txt
setlocal disabledelayedexpansion
echo %VideoURL% &gt; &quot;%filename%&quot; &amp;&amp; del /q %tempFileName%
cscript /nologo /e:javascript &quot;%~dpnx0&quot; &quot;%filename%&quot;
call %AppPath% --socket-timeout 45 --print &quot;&lt;%%%%(webpage_url_domain)s:%%%%(uploader)s&gt;&quot; %%VideoURL%% &gt;&gt; &quot;%filename%&quot;
cscript /nologo /e:javascript &quot;%~dpnx0&quot; &quot;%filename%&quot; /toUTF-8:1
echo.&gt;&gt; &quot;%filename%&quot;
call :size &quot;%filename%&quot;
set tempsize=%filesize%
call %AppPath% --socket-timeout 45 --print formats_table %%VideoURL%% &gt;&gt; &quot;%filename%&quot;
if not errorlevel 0 exit /b
call :size &quot;%filename%&quot;
if %tempsize% == %filesize% exit /b
for /f %%i in (&#039;cscript /nologo /e:javascript &quot;%~dpnx0&quot; &quot;%filename%&quot; /FORMATRECOMMENDATIONS:%enable_format_recommendations%&#039;) do if defined enable_format_recommendations if &quot;%enable_format_recommendations%&quot; == &quot;1&quot; if not &quot;%%i&quot; == &quot;&quot; set format=%%i
if -%1- == ---- exit /b
rem --limit-rate 8.5M
start &quot;yt-dlp: %VideoURL%&quot; %AppPath% -k -o &quot;%template%&quot; --split-chapters --postprocessor-args &quot;SplitChapters+ffmpeg:-map_metadata -1&quot; --video-multistreams --audio-multistreams --windows-filenames --remux-video %extension% --concurrent-fragments 10 --socket-timeout 45 --abort-on-unavailable-fragment --exec &quot;pause &quot; --embed-metadata --format %format% %VideoURL% ^&amp;exit/b
:set_template
set template=%head%%series%%%(title)s [%%(id)s]%suffix%.%%(ext)s
exit /b
:size
set filesize=%~z1
goto:eof */

// Описание работы скрипта на основании подготовленного видео о скачивании с его помошью (с размышлениями о юридических тонкостях при этом),
// статьи в Дзене у меня, также текстов скриптов (там ещё про получение оглавления папки с видеофайлами)
// в Алисе Про: https://alicepro.yandex.ru/expert/projects/5f35ee4ef1a511f081018e7d0d775479
// (этот вариант описательного ИИ может использоваться только на территории Российской Федерации и Республики Беларусь)
// Ссылка на свежий вариант этого батника у меня на GitHub: https://kvk-2015.github.io/y.cmd
// У меня на компьютере установлена кодировка utf-8, если нужно, чтобы скрипт корректно выполнял поиск по регулярным выражениям на кирилице,
// сохраните его в кодировке Windows-1251, если она установлена на вашем компьютере

var fso = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;), fName = &quot;&quot;, newText = &quot;&quot;, WshShell = new ActiveXObject(&quot;WScript.Shell&quot;), url, id, json_url;
var CodePagesTestsDone = false, CodePages = [], q_mark = decodeURIComponent(&quot;%EF%BC%9F&quot;), re_process_marks = new RegExp(&quot;([!&quot; + q_mark + &quot;])\\.(\\s)&quot;, &quot;g&quot;);
var lines, lineIndex, line, oExec, double_quotes = decodeURIComponent(&quot;%EF%BC%82&quot;), colon = decodeURIComponent(&quot;%EF%BC%9A&quot;);
if(url=WSH.Arguments.Named.Item(&quot;GetSmotrimData&quot;)){var duration=&quot;&quot;;
    if(!/:\/\/smotrim\.ru.*\/.*video[\/=](\d+)$/.test(url))WSH.Quit();
    with(str=new ActiveXObject(&quot;ADODB.Stream&quot;)){Type=2; Mode=3;}
    oExec = WshShell.Exec((json_url=&#039;curl.exe --raw &quot;https://player-api.smotrim.ru/api/v1/video/&#039; + (id=RegExp.$1)) + &#039;&quot;&#039;);
    while(!oExec.Status || !oExec.StdOut.AtEndOfStream)lines = oExec.StdOut.ReadAll().replace(/([&quot;}\d\]]|null),([&quot;{\[])/g, &quot;$1,\n$2&quot;).split(&quot;\n&quot;);
    for(lineIndex in lines){
        line = lines[lineIndex];
        if(/&quot;title&quot;:\s*&quot;(.+)&quot;(?:,|$)/.test(line))newText += &quot;. &quot; + DosToWin(decodeURIComponent(encodeURIComponent(RegExp.$1)
            .replace(/(?:%EF%BF%BD){2}/g, &quot;..&quot;))).replace(/\?/g, q_mark).replace(/\\&quot;/g, double_quotes).replace(/:/g, colon);
        if(!new_url &amp;&amp; /&quot;m3u8&quot;:\s*&quot;(.*episode[^&quot;]+)&quot;/.test(line))var new_url = RegExp.$1;
        if(!duration &amp;&amp; /&quot;duration&quot;:\s*(\d+)/.test(line)){dI = parseInt(RegExp.$1, 10); var HH = Math.floor(dI/3600); dI -= HH * 3600;
            var MM = Math.floor(dI/60); dI -= MM * 60; duration = &quot;&quot; + HH + &quot;:&quot; + (&quot;0&quot; + MM).slice(-2) + &quot;:&quot; + (&quot;0&quot; + dI).slice(-2);
        }
    }
    if(new_url &amp;&amp; id &amp;&amp; json_url)WSH.echo(new_url + &quot;,&quot; + id + &quot;,&quot; + json_url.slice(16) + &quot;,&quot; + duration);
    if(newText)newText = newText.slice(2).replace(re_process_marks, &quot;$1$2&quot;);
}
if(WSH.Arguments.Unnamed.Count &amp;&amp; (fso.FileExists(fName=WSH.Arguments.Unnamed(0)) || newText)){
    if(1*WSH.Arguments.Named.Item(&quot;toUTF-8&quot;)){
        oExec = WshShell.Exec(&#039;reg.exe query &quot;HKLM\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage&quot; -v ACP&#039;);
        var Windows_codepage = getCodepageName(oExec);
    } else Windows_codepage = &quot;UTF-8&quot;;
    with(new ActiveXObject(&quot;ADODB.Stream&quot;)){Type=2; Mode=3;
        if(!newText){Open(); Charset=Windows_codepage; LoadFromFile(fName); Position=0; newText=ReadText().replace(/(?:\s*&lt;[^:]*:NA&gt;)?\s*$/g, &quot;&quot;); Close()}
        newText = ((isTemp=/^\d+\.tmp$/.test(fName)) ? newText.replace(/\(/g, &quot;{&quot;).replace(/\)/g, &quot;}&quot;) : newText.replace(/ *\r\n|\n(\r\n)?/g, &quot;\r\n$1&quot;));
        if(fso.FileExists(fName))fso.DeleteFile(fName);
        Open(); Charset=&quot;UTF-8&quot;; Position=0; WriteText(newText + (isTemp ? &quot;&quot; : &quot;\r\n&quot;)); SaveToFile(fName); Close();
    }
}
if(1*WSH.Arguments.Named.Item(&quot;FORMATRECOMMENDATIONS&quot;) &amp;&amp; newText){
    var lines = newText.split(&quot;\r\n&quot;), recommended_audio_format = &quot;&quot;, recommended_video_format = &quot;&quot;, recommended_format = &quot;&quot;;
    var audio_regexp = &quot;&quot;, video_regexp = &quot;&quot;, regexp = &quot;&quot;, page_specific = {
        &quot;AM_Live,interviews_on_vkvideo&quot;:[/:\/\/vkvideo\.ru\/video-(?:21732035|20648295|35758136)_/,
                                        /(^hls\S+_2\D\S*)\s/, /(^hls\S+)\s.+(?:25|30) \|/],
        &quot;vkvideo.ru:Mobile-Review.com&quot;: [/&lt;vkvideo\.ru:Mobile-Review\.com&gt;/, /(^hls\S+_2\D\S*)\s/, /(^hls\S+)\s.+1920x1080\s+25 \|/],
        &quot;rutube.ru:Константин Кулаков&quot;: [/&lt;rutube\.ru:Константин Кулаков&gt;/, /(^default-\S+)\s/]
    }
    for(lineIndex in lines){
        line = lines[lineIndex];
        if(lineIndex&lt;=1)for(var i in page_specific)if(page_specific[i][0].test(line))
            if(page_specific[i].length==3){audio_regexp = page_specific[i][1]; video_regexp = page_specific[i][2]; break}
            else {regexp = page_specific[i][1]; break}
        if(regexp &amp;&amp; regexp.test(line))recommended_format = RegExp.$1;
        else if(!audio_regexp &amp;&amp; !video_regexp &amp;&amp; /(^\S+)\s+mp4\s+1920x1080\s+25\D.*m3u8\s+\|\s+(?:unknown\s+unknown|avc1[.\d]+\s+mp4a[.\d]+)(?:\s|$)/.test(line))recommended_format = RegExp.$1;
        if(/audio only/.test(line)){
            if(audio_regexp){if(audio_regexp.test(line))recommended_audio_format = RegExp.$1}
            else if(/(^hls\S+)\s/.test(line))recommended_audio_format = RegExp.$1;
            else if(!/^hls/.test(recommended_audio_format) &amp;&amp; /(^\S+)\s+m4a/.test(line))recommended_audio_format = RegExp.$1;
        } else if(/video only/.test(line)){
            if(video_regexp){if(video_regexp.test(line))recommended_video_format = RegExp.$1}
            else if(/(^hls\S+)\s/.test(line))recommended_video_format = RegExp.$1;
            else if(!/^hls/.test(recommended_video_format) &amp;&amp; /(^\S+)\s+mp4\s+1920x1080\s+.*avc1/.test(line))recommended_video_format = RegExp.$1;
        }
    }
    if(recommended_format)WSH.echo(recommended_format);
    else WSH.echo(recommended_audio_format &amp;&amp; recommended_video_format ? recommended_audio_format + &quot;+&quot; + recommended_video_format : &quot;&quot;);
}

function getCodepage(oExec){
    while(!oExec.Status || !oExec.StdOut.AtEndOfStream){
        var new_codepage = /^[\s\S]*(?:REG_SZ|:)\s+(\S+)\s*$/.test(oExec.StdOut.ReadAll()) ? RegExp.$1 : &quot;&quot;;
    }
    return new_codepage;
}

function getCodepageName(oExec){
    var commandHead = &#039;reg.exe query &quot;HKCR\\MIME\\Database\\Codepage\\&#039;, codepage, WebCharset;
    oExec = WshShell.Exec(commandHead + (codepage = getCodepage(oExec)) + &#039;&quot; -v BodyCharset&#039;); var tempCodepageName = getCodepage(oExec);
    oExec = WshShell.Exec(commandHead + codepage + &#039;&quot; -v WebCharset&#039;); return (WebCharset = getCodepage(oExec)) ? WebCharset : tempCodepageName;
}
function DosToWin(dosString){
    var result;
    if(!CodePagesTestsDone){
        var oExec = WshShell.Exec(&#039;cmd.exe /c chcp&#039;);   var DOS_codepage = getCodepageName(oExec);
        oExec = WshShell.Exec(&#039;reg.exe query &quot;HKLM\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage&quot; -v ACP&#039;);    var Windows_codepage = getCodepageName(oExec);
        if(DOS_codepage != Windows_codepage)CodePages = [DOS_codepage, Windows_codepage];
        CodePagesTestsDone = true;
    }
    if(!CodePages.length)return dosString;
    with(str){
        Open();
        Charset = CodePages[1];
        WriteText(dosString);
        Position = 0;
        Charset = CodePages[0];
        result = ReadText();
        Close();
    }
    return result;
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (kvk-2019)]]></author>
			<pubDate>Mon, 03 Aug 2026 07:50:27 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=163475#p163475</guid>
		</item>
	</channel>
</rss>
