<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>КББ</title><generator>teletype.in</generator><description><![CDATA[Ёмко об IT, фото, фильмах, книгах, музыке, играх и гик-культуре]]></description><image><url>https://img4.teletype.in/files/72/71/727171d3-ff31-4618-862a-e82870ead774.png</url><title>КББ</title><link>https://teletype.in/@beaverclan</link></image><link>https://teletype.in/@beaverclan?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/beaverclan?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/beaverclan?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Mon, 15 Jun 2026 03:05:29 GMT</pubDate><lastBuildDate>Mon, 15 Jun 2026 03:05:29 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@beaverclan/blogontimewebs3</guid><link>https://teletype.in/@beaverclan/blogontimewebs3?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/blogontimewebs3?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>Хостинг Hugo-блога на S3 Timeweb</title><pubDate>Sat, 13 Jun 2026 00:15:01 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/de/76/de76d744-9a6b-4441-8ca2-03b88d336bc6.png"></media:content><category>Blog</category><description><![CDATA[<img src="https://img4.teletype.in/files/f0/c6/f0c67423-5f38-43cf-bcf2-2c5a7e93c49d.png"></img>Долгое время мой блог жил на VDS — nginx, certbot, systemd-сервисы, бекапы, короче полноценный сервер. В какой-то момент стало лень следить за ещё одной машиной и особенно меня подтолкнули проблемы с разными хостингами и я решил переехать на статический S3-хостинг.]]></description><content:encoded><![CDATA[
  <figure id="foTe" class="m_original">
    <img src="https://img4.teletype.in/files/f0/c6/f0c67423-5f38-43cf-bcf2-2c5a7e93c49d.png" />
  </figure>
  <p id="kp5T">Долгое время мой блог жил на VDS — nginx, certbot, systemd-сервисы, бекапы, короче полноценный сервер. В какой-то момент стало лень следить за ещё одной машиной и особенно меня подтолкнули проблемы с разными хостингами и я решил переехать на статический S3-хостинг.</p>
  <p id="f9Kc">Пост про то — как я переехал, с какими граблями столкнулся и что в итоге получилось.</p>
  <h2 id="почему-timeweb-s3">Почему Timeweb S3</h2>
  <p id="iZHc">Почему именно Timeweb, а не Яндекс Облако или Selectel? Тут всё просто: у меня уже были там аккаунты, а S3 у них стоит копейки. Для статики — идеально.</p>
  <p id="fKiz">Из коробки Timeweb S3 умеет раздавать статический сайт, выдаёт URL вида <code>*.website.twcstorage.ru</code>, поддерживает кастомные заголовки и политики.</p>
  <h2 id="что-нужно">Что нужно</h2>
  <ul id="qJS4">
    <li id="7FQr">Аккаунт в Timeweb (уже был)</li>
    <li id="MEAR">Hugo</li>
    <li id="fRuO">Репозиторий блога на GitHub (уже был)</li>
    <li id="WjTf">Домен (уже был)</li>
  </ul>
  <h2 id="шаг-1-создание-бакета">Шаг 1: Создание бакета</h2>
  <ol id="4pHe">
    <li id="MN1U">Заходим в панель Timeweb → S3 → Создать бакет</li>
    <li id="LL1P">Выбираем регион, имя бакета</li>
    <li id="Mqk0">После создания открываем бакет → Настройки → Хостинг статического сайта → Включаем</li>
    <li id="3ZPg">Получаем URL: <code>https://&lt;id&gt;.website.twcstorage.ru</code></li>
  </ol>
  <h2 id="шаг-2-s3-ключи">Шаг 2: S3-ключи</h2>
  <p id="ImNG">В панели Timeweb идём в сервисные аккаунты → создаём ключ с доступом к бакету (на запись и чтение). Нам понадобятся:</p>
  <ul id="zcdA">
    <li id="VP5n"><code>AWS_ACCESS_KEY_ID</code></li>
    <li id="MK2D"><code>AWS_SECRET_ACCESS_KEY</code></li>
    <li id="snl7"><code>AWS_ENDPOINT_URL</code> — <code>https://s3.twcstorage.ru</code></li>
    <li id="PKhx">И имя бакета</li>
  </ul>
  <h2 id="шаг-3-github-actions">Шаг 3: GitHub Actions</h2>
  <p id="lfMF">Деплой настроил через GitHub Actions. Workflow выглядит так:</p>
  <pre id="9uie">name: Deploy blog to S3

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: peaceiris/actions-hugo@v3
        with:
          extended: true

      - run: hugo --gc

      - uses: jakejarvis/s3-sync-action@master
        with:
          args: --delete
        env:
          AWS_S3_BUCKET: ${{ secrets.AWS_BUCKET_NAME }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_ENDPOINT_URL: ${{ secrets.AWS_ENDPOINT_URL }}
</pre>
  <p id="HyxA">Секреты (<code>AWS_*</code>) храню в настройках репозитория GitHub — Settings → Secrets and variables → Actions.</p>
  <h2 id="шаг-4-деплой">Шаг 4: Деплой</h2>
  <p id="fh1C">Пушим в main:</p>
  <pre id="1vJW">git push origin main
</pre>
  <p id="aGH9">GitHub Actions собирает сайт и синхронизирует с бакетом. Всё, сайт на S3, никаких ssh и ручных заливок.</p>
  <h2 id="шаг-5-домены-не-так-всё-просто">Шаг 5: Домены (не так всё просто)</h2>
  <p id="g7dg">Настраиваем CNAME в DNS:</p>
  <pre id="AAlh">blog.tatarinovms.ru → s3.twcstorage.ru
blog.tatarinovms.space → s3.twcstorage.ru
</pre>
  <p id="N0ZI">Ждём, пока DNS обновится, открываем браузер… и получаем <code>AccessDenied</code>.</p>
  <h3 id="подводный-камень-кастомные-домены-не-работают">Подводный камень: кастомные домены не работают</h3>
  <p id="B8Uu">Как оказалось, Timeweb S3 <a href="https://timeweb.cloud/docs/s3-storage/supported-features/static-websites#ogranicheniya" target="_blank">не поддерживает кастомные домены</a>. Вообще. Только их <code>*.website.twcstorage.ru</code>. На момент написания поста ответ поддержки это подтвердил.</p>
  <p id="YhcL">Есть два пути:</p>
  <p id="1Bix"><strong>Вариант 1: CloudFlare</strong> Меняем NS на CloudFlare, он проксирует запросы на S3-эндпоинт и выдаёт свой SSL. VDS не нужен. Бесплатно. Но мы знаем как в некоторых регионах работает CloudFlare, скажем мягко - с перебоями.</p>
  <p id="FMwK"><strong>Вариант 2: nginx reverse proxy</strong> Пришла простая идея, так как есть в загашнике VDS, то мы ставим nginx на VDS, он проксирует кастомные домены на S3 URL. SSL через certbot. VDS всё равно есть под другие задачи. Конфиг nginx:</p>
  <pre id="WmqL">server {
    listen 80 default_server;
    server_name blog.tatarinovms.ru blog.tatarinovms.space;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name blog.tatarinovms.ru blog.tatarinovms.space;

    ssl_certificate /etc/letsencrypt/live/blog.tatarinovms.space/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog.tatarinovms.space/privkey.pem;

    location / {
        proxy_pass https://id.website.twcstorage.ru;
        proxy_ssl_verify off;
        proxy_ssl_server_name on;
        proxy_set_header Host id.website.twcstorage.ru;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
</pre>
  <p id="FouX">SSL получил через certbot:</p>
  <pre id="6kJP">certbot --nginx -d blog.tatarinovms.ru -d blog.tatarinovms.space
</pre>
  <h2 id="итоговая-схема">Итоговая схема</h2>
  <pre id="NmyK">Пуш в main → GitHub Actions → Hugo build → aws s3 sync → S3 бакет → DNS: blog.tatarinovms.ru / blog.tatarinovms.space → A → VDS → nginx reverse proxy → S3 (*.website.twcstorage.ru)
</pre>
  <p id="8g5B">При пуше в main GitHub Actions сам собирает Hugo и синхронизирует с S3 — nginx просто проксирует то, что уже лежит в бакете. Редеплой занимает меньше минуты.</p>
  <p id="jUw3">Timeweb S3 как хостинг статики — отличное решение. Но с кастомными доменами придётся извернуться. Надеюсь, когда-нибудь они добавят эту возможность, но пока — nginx.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/finetune</guid><link>https://teletype.in/@beaverclan/finetune?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/finetune?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>FineTune — бесплатный аудио-микшер для macOS</title><pubDate>Thu, 28 May 2026 16:03:17 GMT</pubDate><description><![CDATA[<img src="https://blog.tatarinovms.space/images/posts/finetune/logo.webp"></img>FineTune — это бесплатная open-source утилита для macOS, которая живёт в меню-баре и даёт полный контроль над аудио на системном уровне. Регулировка громкости каждого приложения независимо, маршрутизация звука на разные устройства, 10-полосный эквалайзер и коррекция АЧХ для наушников — всё в одном окне.]]></description><content:encoded><![CDATA[
  <figure id="x4gH" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/finetune/logo.webp" width="800" />
  </figure>
  <h2 id="что-такое-finetune">Что такое FineTune?</h2>
  <p id="HB1K">FineTune — это бесплатная open-source утилита для macOS, которая живёт в меню-баре и даёт полный контроль над аудио на системном уровне. Регулировка громкости каждого приложения независимо, маршрутизация звука на разные устройства, 10-полосный эквалайзер и коррекция АЧХ для наушников — всё в одном окне.</p>
  <p id="9piW">Для перехвата аудиопотоков FineTune создаёт виртуальное аудиоустройство. Оно появляется в системных настройках звука и работает как прослойка между приложениями и вашими колонками/наушниками.</p>
  <p id="c6RU">Написан на SwiftUI, требует macOS 15.0+.</p>
  <h2 id="основные-возможности">Основные возможности</h2>
  <h3 id="управление-громкостью">Управление громкостью</h3>
  <ul id="XUet">
    <li id="mqq7"><strong>Per-app громкость</strong> — отдельный слайдер и mute для каждого приложения</li>
    <li id="f3op"><strong>Pinned apps</strong> — закрепить приложение в меню-баре, даже когда оно не воспроизводит звук (удобно настроить EQ и маршрутизацию заранее)</li>
    <li id="Ubss"><strong>Ignore apps</strong> — полностью исключить приложение из управления FineTune</li>
    <li id="VzXt"><strong>Scroll-wheel</strong> — наведите курсор на любой слайдер и крутите колёсико</li>
  </ul>
  <h3 id="горячие-клавиши">Горячие клавиши</h3>
  <ul id="UFfO">
    <li id="LXwg"><strong>Глобальные хоткеи</strong> — назначьте свои комбинации на App Volume Up/Down и Mute. Работают даже когда приложение свёрнуто</li>
    <li id="3DdG"><strong>Toggle Popup</strong> — повесьте хоткей на открытие/закрытие окна FineTune, работает из полноэкранных приложений</li>
    <li id="G9CD"><strong>Навигация внутри попапа</strong> — стрелки <code>↑↓</code> между строками, <code>←→</code> регулировка громкости, <code>M</code>mute, <code>Return/Space</code> активация, <code>Tab</code> переключение вкладок устройств</li>
  </ul>
  <h3 id="маршрутизация">Маршрутизация</h3>
  <ul id="ulU3">
    <li id="4T2Q"><strong>Multi-device output</strong> — вывод звука на несколько устройств одновременно</li>
    <li id="MqmG"><strong>Audio routing</strong> — отправлять разные приложения на разные устройства</li>
    <li id="5tvL"><strong>Device priority</strong> — автопереключение при подключении нового устройства</li>
    <li id="hetq"><strong>Auto-restore</strong> — при переподключении устройства настройки (громкость, маршрут, EQ) восстанавливаются автоматически</li>
  </ul>
  <h3 id="эквалайзер">Эквалайзер</h3>
  <ul id="XRNY">
    <li id="8x5C"><strong>10 полос</strong>, 20 готовых пресетов</li>
    <li id="ppow"><strong>Пользовательские пресеты</strong> — сохраняйте свои настройки и применяйте к разным приложениям</li>
    <li id="Cwzm"><strong>AutoEQ headphone correction</strong> — коррекция АЧХ под конкретную модель наушников из базы AutoEQ (тысячи профилей). Можно импортировать свои ParametricEQ.txt</li>
    <li id="b1f4"><strong>Загрузка пресета</strong> — выбрав пресет для своих наушников, FineTune запоминает его и применяет автоматически при каждом подключении этой модели</li>
    <li id="eutN"><strong>Loudness compensation</strong> — автоматическая коррекция низких и высоких частот на малой громкости по стандарту ISO 226:2023</li>
  </ul>
  <h3 id="системное">Системное</h3>
  <ul id="YOCS">
    <li id="qoSj"><strong>Input device control</strong> — уровень микрофона</li>
    <li id="HUp6"><strong>Alert volume</strong> — громкость системных уведомлений</li>
    <li id="Aiuu"><strong>DDC</strong> — регулировка громкости внешних мониторов</li>
    <li id="yjVx"><strong>Volume HUD</strong> — встроенный индикатор громкости (Tahoe или Classic стиль)</li>
    <li id="Qj8J"><strong>Медиа-клавиши F10-F12</strong> — работают даже на USB DAC и HDMI, где штатные клавиши macOS бесполезны</li>
    <li id="mly5"><strong>Bluetooth</strong> — подключение устройств прямо из меню-бара</li>
    <li id="mUyX"><strong>URL schemes</strong> — автоматизация через shell, Shortcuts или Raycast’о подобное</li>
  </ul>
  <h2 id="установка">Установка</h2>
  <pre id="kHTU">brew install --cask finetune
</pre>
  <p id="9llU">Или скачайте DMG с <a href="https://github.com/ronitsingh10/FineTune/releases/latest" target="_blank">GitHub Releases</a>.</p>
  <h2 id="быстрый-старт">Быстрый старт</h2>
  <ol id="CW8s">
    <li id="5mkA">Запустите FineTune из папки Applications</li>
    <li id="82RN">Разрешите <strong>Screen &amp; System Audio Recording</strong> — это необходимо для перехвата аудиопотоков</li>
    <li id="PTmo">Нажмите на иконку FineTune в меню-баре — приложения, воспроизводящие звук, появятся автоматически</li>
  </ol>
  <p id="BoLb">Готово. Регулируйте громкость, маршрутизируйте звук, настраивайте EQ.</p>
  <h2 id="полезные-фышки">Полезные фЫшки</h2>
  <ul id="BauV">
    <li id="swJr"><strong>Автопереключение на Bluetooth-гарнитуру</strong>: откройте edit mode (карандаш) и перетащите устройство выше встроенных динамиков — FineTune будет переключаться на него при подключении</li>
    <li id="8F7i"><strong>Управление с клавиатуры</strong>: откройте попап и пользуйтесь стрелками.</li>
    <li id="SHMR"><strong>URL schemes</strong> — automate volume, mute, device routing, and more from scriptsFineTune понимает URL-команды формата <code>finetune://</code>.<code>finetune://set-volumes?app=com.spotify.client&amp;volume=50 finetune://set-mute?app=com.spotify.client&amp;muted=true finetune://toggle-mute?app=com.hnc.Discord finetune://set-device?app=com.apple.Music&amp;device=DEVICE_UID finetune://reset </code></li>
  </ul>
  <figure id="x9TA" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/finetune/1.webp" width="500" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/qwen3asronmacos</guid><link>https://teletype.in/@beaverclan/qwen3asronmacos?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/qwen3asronmacos?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>Qwen3 ASR на macOS</title><pubDate>Sun, 03 May 2026 11:51:17 GMT</pubDate><description><![CDATA[<img src="https://blog.tatarinovms.space/images/posts/qwen3asronmacos/logo.webp"></img>В этом гайде я покажу, как развернуть и запустить модель распознавания речи Qwen3‑ASR через пакет mlx-qwen3-asr на macOS с M-чипом. Решение позволяет транскрибировать аудио из видеофайлов с поддержкой русского языка и сохранять результат в разных форматах: SRT, VTT, TXT, JSON.]]></description><content:encoded><![CDATA[
  <figure id="qDLy" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/qwen3asronmacos/logo.webp" width="800" />
  </figure>
  <p id="H5S1">В этом гайде я покажу, как развернуть и запустить модель распознавания речи Qwen3‑ASR через пакет mlx-qwen3-asr на macOS с M-чипом. Решение позволяет транскрибировать аудио из видеофайлов с поддержкой русского языка и сохранять результат в разных форматах: SRT, VTT, TXT, JSON.</p>
  <h1 id="что-такое-mlx-qwen3-asr">Что такое mlx-qwen3-asr?</h1>
  <p id="DpqW"><a href="https://github.com/moona3k/mlx-qwen3-asr" target="_blank">mlx-qwen3-asr</a> - это Python‑пакет, предоставляющий удобный интерфейс к модели Qwen3‑ASR‑1.7B от Alibaba Cloud, оптимизированной для работы на чипах Apple Silicon через фреймворк MLX. Модель поддерживает несколько языков, включая наш родной русский, и позволяет получать транскрипцию с тайм‑кодами.</p>
  <h2 id="требования">Требования</h2>
  <ul id="brvV">
    <li id="Bjzn">macOS</li>
    <li id="aSjr">Установленный Python 3.11</li>
    <li id="aImQ">Руки</li>
    <li id="syvz">Свободное место на диске (модель ~3 ГБ)</li>
  </ul>
  <h1 id="установка-и-настройка">Установка и настройка</h1>
  <h2 id="подготовка-директории-проекта">Подготовка директории проекта</h2>
  <p id="P4NZ">Создайте отдельную папку для проекта и перейдите в неё, у меня будет так:</p>
  <pre id="PQaw">mkdir -p ~/Documents/ai/asr
cd ~/Documents/ai/asr
</pre>
  <h2 id="создание-виртуального-окружения">Создание виртуального окружения</h2>
  <pre id="QSXM">python3.11 -m venv venv
</pre>
  <h2 id="активация-окружения">Активация окружения</h2>
  <p id="wtYF">Активируйте виртуальное окружение:</p>
  <pre id="Yv0b">source venv/bin/activate
</pre>
  <h2 id="обновление-pip-и-установка-пакета">Обновление pip и установка пакета</h2>
  <p id="jKp5">Обновите менеджер пакетов и установите mlx-qwen3-asr:</p>
  <pre id="ex17">pip install --upgrade pip
pip install mlx-qwen3-asr
</pre>
  <p id="Qrot">Установка может занять несколько минут — загружаются зависимости и модель.</p>
  <h2 id="создание-скрипта-автоматизации">Создание скрипта автоматизации</h2>
  <p id="QI99">Чтобы не вводить команды вручную каждый раз, создадим shell‑скрипт с небольшим интерактивным интерфейсом.</p>
  <h3 id="создайте-файл-скрипта">Создайте файл скрипта</h3>
  <ul id="m9UL">
    <li id="KfxS">Создадим скрипт в любимом текстовом редакторе:</li>
  </ul>
  <pre id="76SI">vim asr_process.sh
</pre>
  <ul id="uQps">
    <li id="RADG">Вставьте этот <a href="https://blog.tatarinovms.space/static/scripts/qwen3asronmacos/asr_process.sh" target="_blank">код</a></li>
    <li id="FFX8">Укажите настройку <code>VENV_BIN=</code>, где будет путь к созданной вами папке.</li>
    <li id="9JJi">Сохраняем файл</li>
    <li id="hzFO">Делаем скрипт исполняемым</li>
  </ul>
  <pre id="dNfd">chmod +x asr_process.sh
</pre>
  <h2 id="отправляем-файл-на-распознавание">Отправляем файл на распознавание</h2>
  <ul id="zhFw">
    <li id="hDj1">Запускаем скрипт</li>
  </ul>
  <pre id="Pxyg">./asr_process.sh
</pre>
  <ul id="SogN">
    <li id="UtVV">откроет диалоговое окно для выбора файла</li>
    <li id="DBQx">потом скрипт предложит выбрать формат вывода</li>
    <li id="dS5f">позволит указать папку для сохранения</li>
    <li id="J5mK">запустится распознавание и покажет прогресс (при первом запуске модель скачается)</li>
  </ul>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/voxcpm</guid><link>https://teletype.in/@beaverclan/voxcpm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/voxcpm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>VoxCPM - на ноуте. Клонируем свой голос</title><pubDate>Sun, 26 Apr 2026 17:26:16 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/35/72/35721e82-9c8b-4e50-926b-70083be2ca65.png"></media:content><category>Blog</category><description><![CDATA[<img src="https://blog.tatarinovms.space/images/posts/voxcpm/logo.webp"></img>Данное руководство содержит пошаговые инструкции по установке и запуску VoxCPM на macOS с процессорами Apple Silicon. Игрался на своем ноуте.]]></description><content:encoded><![CDATA[
  <figure id="Id5N" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/voxcpm/logo.webp" width="800" />
  </figure>
  <h1 id="развёртывание-voxcpm-на-macbook-с-чипом-apple-silicon">Развёртывание VoxCPM на MacBook с чипом Apple Silicon</h1>
  <p id="Gh74">Данное руководство содержит пошаговые инструкции по установке и запуску <a href="https://github.com/OpenBMB/VoxCPM" target="_blank">VoxCPM</a> на macOS с процессорами Apple Silicon. Игрался на своем ноуте.</p>
  <h2 id="скачиваем-репозиторий-проекта">Скачиваем репозиторий проекта</h2>
  <p id="snAR">Переходим в папку, где у вас всё будет аккуратно лежать и скачиваем репу:</p>
  <pre id="6Xat">git clone https://github.com/OpenBMB/VoxCPM.git
cd VoxCPM
</pre>
  <h2 id="настройка-доступа-к-hugging-face">Настройка доступа к Hugging Face</h2>
  <p id="C49j">Для ускорения загрузки моделей и повышения лимитов запросов рекомендуется настроить токен доступа на Hugging Face</p>
  <h3 id="получение-токена">Получение токена</h3>
  <ol id="TSEf">
    <li id="Mod9">Перейдите на <a href="https://huggingface.co/settings/tokens" target="_blank">https://huggingface.co/settings/tokens</a></li>
    <li id="WUoP">Создайте новый токен с правами <strong>Read</strong></li>
    <li id="LtUN">Скопируйте токен (формат: <code>hf_...</code>)</li>
  </ol>
  <h3 id="настройка-токена">Настройка токена</h3>
  <p id="ZO7z"><strong>Способ 1: Через huggingface-cli</strong></p>
  <pre id="mmYn">pip install -U huggingface_hub
hf auth login
# Вставьте токен при запросе
</pre>
  <p id="3ooi"><strong>Способ 2: Через переменную окружения</strong></p>
  <pre id="tu4Z"># Временно для сессии
export HF_TOKEN=&quot;hf_ваш_токен_здесь&quot;

# Или навсегда (добавить в ~/.zshrc)
echo &#x27;export HF_TOKEN=&quot;hf_ваш_токен_здесь&quot;&#x27; &gt;&gt; ~/.zshrc
source ~/.zshrc
</pre>
  <h2 id="установка-python-310-через-pyenv">Установка Python 3.10+ через pyenv</h2>
  <h3 id="установка-homebrew-если-не-установлен-но-навряд-ли-конечно">Установка Homebrew (если не установлен, но навряд ли, конечно)</h3>
  <pre id="2Xt7">/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;
</pre>
  <h3 id="установка-pyenv-и-зависимостей">Установка pyenv и зависимостей</h3>
  <pre id="9gRa">brew install pyenv openssl readline sqlite3 xz zlib pkgconf autoconf
</pre>
  <h3 id="настройка-окружения-оболочки">Настройка окружения оболочки</h3>
  <p id="8IBO">Добавьте следующие строки в <code>~/.zshrc</code>:</p>
  <pre id="nQdC">export PYENV_ROOT=&quot;$HOME/.pyenv&quot;
export PATH=&quot;$PYENV_ROOT/bin:$PATH&quot;
eval &quot;$(pyenv init --path)&quot;
eval &quot;$(pyenv init -)&quot;
</pre>
  <p id="KWgk">Примените изменения:</p>
  <pre id="Kr3r">source ~/.zshrc
</pre>
  <h3 id="установка-python-31014">Установка Python 3.10.14</h3>
  <pre id="eZcN">pyenv install 3.10.14
</pre>
  <h3 id="настройка-версии-для-проекта">Настройка версии для проекта</h3>
  <p id="U8EM">Перейдите в папку проекта, которую мы скачали ранее и указываем локальную версию Python:</p>
  <pre id="T3Rc">cd ~/Documents/ai/VoxCPM 
pyenv local 3.10.14
python --version  # Должно вывести: Python 3.10.14
</pre>
  <h2 id="настройка-проекта-и-установка-зависимостей">Настройка проекта и установка зависимостей</h2>
  <h3 id="создание-виртуального-окружения">Создание виртуального окружения</h3>
  <pre id="fHZ0"># В папке проекта
python -m venv venv
source venv/bin/activate
pip install --upgrade pip
</pre>
  <h3 id="установка-проекта-в-режиме-разработки">Установка проекта в режиме разработки</h3>
  <pre id="6BbR">pip install -e .
</pre>
  <h3 id="проверка-установки">Проверка установки</h3>
  <pre id="KE1d">which voxcpm
# Должно указывать на путь внутри venv

voxcpm --help
# Должно отобразить справку по командам и доступным флагам
</pre>
  <h3 id="скачиваем-модель-в-папку">Скачиваем модель в папку</h3>
  <p id="V0TC">Делаем папку для модели и качаем модель:</p>
  <pre id="Ptl3">mkdir -p models/VoxCPM-2B
hf download openbmb/VoxCPM2 --local-dir ./models/VoxCPM2
</pre>
  <h2 id="использование-через-cli">Использование через CLI</h2>
  <h3 id="базовый-синтаксис">Базовый синтаксис</h3>
  <p id="jQ7M">В без все просто:</p>
  <pre id="CvTx">voxcpm &lt;режим&gt; [параметры]
</pre>
  <p id="TQmi">Но мы пойдём путём клонирования своего голоса для озвучки текста.</p>
  <h3 id="готовим-файл-для-клонирования">Готовим файл для клонирования</h3>
  <p id="DrjQ">Я просто записал аудиосообщение в одном голубом мессенджере, сохранил его и перекодировал через ffmpeg в wav. Текст сообщения был такой: Это образец моего голоса. Я говорю здесь целых пять секунд.</p>
  <p id="HGR6">Файл с текстом и аудио сохранил в папке ./ref. Т. е. ref.txt и ref.wav</p>
  <h3 id="готовим-текст-для-озвучки">Готовим текст для озвучки</h3>
  <p id="byzC">Создам папку output и inpit чтобы папку не замусоривать. Создаю текст для озвучки:</p>
  <pre id="vV2y">vim ./inpit/anime.txt
</pre>
  <p id="bXiU">Накидал туда описание аниме - <a href="https://hd.kinopoisk.ru/film/b04631f828704a91b2c4730cf1c32699" target="_blank">Ателье колдовских колпаков</a></p>
  <h3 id="запускаем-озвучку-с-клонированием-нашего-голоса">Запускаем озвучку с клонированием нашего голоса</h3>
  <p id="k30l">Запускаем озвучку нашего текста с клонированием голоса в папку output:</p>
  <pre id="IcdW">voxcpm clone --text &quot;$(cat ./inpit/anime.txt)&quot; --prompt-audio ./ref/ref.wav --prompt-text &quot;$(cat ./ref/ref.txt)&quot; --reference-audio ./ref/ref.wav --output ./output/anime_18.wav --model-path ./models/VoxCPM2 --device mps --no-optimize --cfg-value 1.8 --inference-timesteps 20 --normalize --no-denoiser
</pre>
  <h3 id="что-у-нас-по-параметрам">Что у нас по параметрам?</h3>
  <p id="Pkth">Параметр</p>
  <p id="lKG2">Значение в команде</p>
  <p id="2fJZ">Назначение</p>
  <p id="cZQq"><code>voxcpm clone</code></p>
  <p id="fXwd"><code>clone</code></p>
  <p id="i9Fc">Активация режима клонирования голоса</p>
  <p id="o0gO"><code>--text</code></p>
  <p id="yx27"><code>&quot;$(cat ./inpit/anime.txt)&quot;</code></p>
  <p id="3vRL">Целевой текст для генерации</p>
  <p id="MVHt"><code>--prompt-audio</code></p>
  <p id="cF0I"><code>./ref/ref.wav</code></p>
  <p id="t0Z6">Аудио-референс</p>
  <p id="hCLk"><code>--prompt-text</code></p>
  <p id="uHDf"><code>&quot;$(cat ./ref/ref.txt)&quot;</code></p>
  <p id="8qsw">Точная транскрипция <code>prompt-audio</code></p>
  <p id="WvYm"><code>--reference-audio</code></p>
  <p id="viCK"><code>./ref/ref.wav</code></p>
  <p id="AeX3">Аудио-референс для тембральной идентичности</p>
  <p id="aQ72"><code>--output</code></p>
  <p id="eCSx"><code>./output/anime_18.wav</code></p>
  <p id="Vqfu">Путь к выходному файлу</p>
  <p id="WIPA"><code>--model-path</code></p>
  <p id="Gjg0"><code>./models/VoxCPM2</code></p>
  <p id="YCvs">Локальный каталог с весами модели</p>
  <p id="6f01"><code>--device</code></p>
  <p id="93G5"><code>mps</code></p>
  <p id="kQWd">Платформа на которой мы играемся</p>
  <p id="KT3S"><code>--no-optimize</code></p>
  <p id="Y1j8"><em>без значения</em></p>
  <p id="sXTW">Отключение <code>torch.compile</code></p>
  <p id="B0ER"><code>--cfg-value</code></p>
  <p id="VLUk"><code>1.8</code></p>
  <p id="NOvi">Значение Classifier-Free Guidance</p>
  <p id="wbf1"><code>--inference-timesteps</code></p>
  <p id="YXSN"><code>20</code></p>
  <p id="FXOK">Количество шагов диффузионного декодера</p>
  <p id="830G"><code>--normalize</code></p>
  <p id="BdLc"><em>без значения</em></p>
  <p id="dlwR">Нормализация громкости выхода</p>
  <p id="AvqR"><code>--no-denoiser</code></p>
  <p id="THKW"><em>без значения</em></p>
  <p id="envz">Отключение модуля ZipEnhancer</p>
  <h3 id="результат">Результат</h3>
  <p id="V13l">На выходе получился файл 35.02. Послушать его можно ниже:</p>
  <p id="1m1X"><a href="https://blog.tatarinovms.space/audio/voxcpm/output.mp3" target="_blank">Скачать запись</a></p>
  <figure id="AdV3" class="m_column">
    <iframe src="https://www.youtube.com/embed/TS3jRcnweWY?autoplay=0&loop=0&mute=0"></iframe>
    <figcaption>ютуб</figcaption>
  </figure>
  <figure id="p4F9" class="m_column">
    <iframe src="https://rutube.ru/play/embed/e9b02da8de79e9494f3959cfece86918/"></iframe>
    <figcaption>рутуб</figcaption>
  </figure>
  <figure id="9sta" class="m_column">
    <iframe src="https://vk.com/video_ext.php?oid=-230469137&id=456239119&autoplay=0"></iframe>
    <figcaption>вк видео</figcaption>
  </figure>
  <p id="FYKn"></p>
  <h2 id="литература-для-изучения">Литература для изучения</h2>
  <ul id="bt54">
    <li id="Baz8">GitHub репозиторий: <a href="https://github.com/OpenBMB/VoxCPM" target="_blank">https://github.com/OpenBMB/VoxCPM</a></li>
    <li id="KkuA">Страница модели на Hugging Face: <a href="https://huggingface.co/openbmb/VoxCPM2" target="_blank">https://huggingface.co/openbmb/VoxCPM2</a></li>
  </ul>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/synctogit</guid><link>https://teletype.in/@beaverclan/synctogit?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/synctogit?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>Синхронизация кода в два репозитория одновременно</title><pubDate>Tue, 21 Apr 2026 19:28:52 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/6c/4f/6c4f1c6d-5012-4a37-8ea0-d35943788975.png"></media:content><category>Blog</category><description><![CDATA[<img src="https://img4.teletype.in/files/f4/7d/f47d57b0-4b14-4c17-b2c1-f538fb36e8ad.png"></img>В условиях турбулентной работы облачных сервисов (снова так скажем) вопрос избыточности хранения кода становится актуальным. Держать проект только на GitHub — это риск. Решением может стать зеркалирование кода в другой сервис, например, на GitVerse.]]></description><content:encoded><![CDATA[
  <figure id="pUWv" class="m_column">
    <img src="https://img4.teletype.in/files/f4/7d/f47d57b0-4b14-4c17-b2c1-f538fb36e8ad.png" width="1424" />
  </figure>
  <p id="r3zy">В условиях турбулентной работы облачных сервисов (снова так скажем) вопрос избыточности хранения кода становится актуальным. Держать проект только на GitHub — это риск. Решением может стать зеркалирование кода в другой сервис, например, на GitVerse.</p>
  <p id="l7KB">Обычно мы привыкли, что один <code>remote</code> (например, <code>origin</code>) привязан к одному URL. Но Git позволяет добавить несколько URL для push-операций в один remote.</p>
  <h3 id="PajP">Как это настроить</h3>
  <p id="1jAd">Если у вас уже есть основной репозиторий на GitHub, достаточно добавить второй URL для отправки данных:</p>
  <pre id="QRad">git remote set-url --add --push origin git@gitverse.ru:tatarinovms/ShadowRocketSimpleConfig.git
</pre>
  <p id="SQC6">Теперь при выполнении команды <code>git push origin</code> ваши изменения полетят сразу в оба репозитория.</p>
  <h3 id="hnjv">Нюансы с конфликтами</h3>
  <p id="oYBm">Главная проблема возникает, когда в одном из зеркал есть изменения, которых нет в другом (например, вы отредактировали README прямо в веб-интерфейсе GitVerse). В этом случае обычный push будет отклонен.</p>
  <p id="v8pg">Решить это можно через создание временного remote для «проблемного» зеркала и слияние веток:</p>
  <ol id="fet7">
    <li id="lb7T">Добавляем зеркало как отдельный remote:<code>git remote add gitverse git@gitverse.ru:tatarinovms/ShadowRocketSimpleConfig.git </code></li>
    <li id="YDZ7">Подтягиваем изменения, разрешая несвязанные истории:<code>git pull gitverse main --no-rebase --allow-unrelated-histories </code></li>
    <li id="FNnm">После разрешения конфликтов снова пушим всё в <code>origin</code>.</li>
  </ol>
  <p id="jKqx">Теперь код синхронизирован, а вы спите спокойно, зная, что копия вашего проекта лежит на разных площадках.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/podsync</guid><link>https://teletype.in/@beaverclan/podsync?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/podsync?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>Podsync - YouTube канал в подкаст-приемник</title><pubDate>Sun, 12 Apr 2026 14:01:27 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/07/93/0793e1f1-591a-48a0-bd29-95d73c38e184.png"></media:content><category>Blog</category><description><![CDATA[<img src="https://blog.tatarinovms.space/images/posts/podsync/logo.webp"></img>Podsync — маленький проектик на go, который преобразует каналы с YouTube или Vimeo в обычные подкаст-фиды (RSS). Идея проста: у меня есть каналы, которые я больше слушаю, чем смотрю, и мне хотелось бы делать это в моём подкаст-приёмнике. Гайд будет на Debian-based системы.]]></description><content:encoded><![CDATA[
  <figure id="j1gZ" class="m_retina">
    <img src="https://blog.tatarinovms.space/images/posts/podsync/logo.webp" width="1344" />
  </figure>
  <p id="JCSQ">Podsync — маленький проектик на go, который преобразует каналы с YouTube или Vimeo в обычные подкаст-фиды (RSS). Идея проста: у меня есть каналы, которые я больше слушаю, чем смотрю, и мне хотелось бы делать это в моём подкаст-приёмнике. Гайд будет на Debian-based системы.</p>
  <h2 id="как-это-работает">Как это работает</h2>
  <p id="lkiv">Принцип работы Podsync довольно простой:</p>
  <ol id="LBrG">
    <li id="H2nY">В конфиге прописываем каналы</li>
    <li id="Hd2o">Podsync по расписанию проверяет обновления</li>
    <li id="ySm7">Скачивает новые видео через yt-dlp и конвертирует их в аудио в MP3 через ffmpeg или оставляет видео. Тут уж как хотите.</li>
    <li id="0D3o">Генерирует RSS-фид, доступный по HTTP/HTTPS</li>
  </ol>
  <p id="UXGH">Вы просто добавляете ссылку вида <code>https://your-domain.com/feed_id.xml</code> в подкаст-клиент — и всё работает.</p>
  <h2 id="установка-зависимостей">Установка зависимостей</h2>
  <p id="tOdq">Для работы Podsync нужны <code>yt-dlp</code>, <code>ffmpeg</code> и <code>deno</code> (как JS runtime для yt-dlp на всякий случай):</p>
  <pre id="Mbyk">apt update &amp;&amp; apt install -y yt-dlp ffmpeg curl
</pre>
  <p id="XTC9">Deno устанавливается через официальный скрипт:</p>
  <pre id="Y1O8">curl -fsSL https://deno.land/install.sh | sh
</pre>
  <p id="7MxG">Также понадобится Go, если планируете собирать из исходников:</p>
  <pre id="Zeyp">apt install -y golang
</pre>
  <h2 id="установка-podsync">Установка Podsync</h2>
  <h3 id="вариант-a-сборка-из-исходников">Вариант A: Сборка из исходников</h3>
  <pre id="retv">git clone https://github.com/mxpv/podsync /mnt/dietpi_userdata/podsync
cd /mnt/dietpi_userdata/podsync
make
</pre>
  <h3 id="вариант-бэ-готовый-бинарь">Вариант Бэ: Готовый бинарь</h3>
  <p id="U8Wn">Скачиваем с <a href="https://github.com/mxpv/podsync/releases" target="_blank">GitHub Releases</a>:</p>
  <pre id="SeE6">cd /mnt/dietpi_userdata/podsync
curl -L -o podsync &quot;https://github.com/mxpv/podsync/releases/download/v2.8.0/podsync-v2.8.0-linux-amd64&quot;
chmod +x podsync
</pre>
  <h3 id="вариант-цэ-docker">Вариант Цэ: Docker</h3>
  <p id="jZPr">Если предпочитаете контейнеры:</p>
  <pre id="7wvj">services:
  podsync:
    image: ghcr.io/mxpv/podsync
    container_name: podsync
    volumes:
      - ./data:/app/data/
      - ./db:/app/db/
      - ./config.toml:/app/config.toml
    ports:
      - 8181:8080
</pre>
  <p id="SFhS">Запуск:</p>
  <pre id="1PpR">docker compose up -d
</pre>
  <h2 id="youtube-data-api-v3-ключ">YouTube Data API v3 ключ</h2>
  <p id="YnNI">Ключевой момент — для работы Podsync нужен <strong>YouTube Data API v3 ключ</strong>. Без него парсинг каналов не работает.</p>
  <p id="D3X8">Получить ключ можно здесь: <a href="https://developers.google.com/youtube/registering_an_application" target="_blank">https://developers.google.com/youtube/registering_an_application</a></p>
  <p id="if7x">В конфиге нужно указать ключ в секции:</p>
  <pre id="nujC">[tokens]
youtube = &quot;YOUR_YOUTUBE_API_KEY&quot;
</pre>
  <p id="y8yT">Или даже несколько для ротации:</p>
  <pre id="2DlI">youtube = [&quot;KEY1&quot;, &quot;KEY2&quot;, &quot;KEY3&quot;]
</pre>
  <h2 id="настройка-конфигурации">Настройка конфигурации</h2>
  <p id="rgyM">Собственно и сам конфиг. Создаём файл <code>config.toml</code> на основе примера:</p>
  <pre id="Jzne">cp /mnt/dietpi_userdata/podsync/config.toml.example /mnt/dietpi_userdata/podsync/config.toml
nano /mnt/dietpi_userdata/podsync/config.toml
</pre>
  <p id="cJUH">Для примера:</p>
  <pre id="n90n">[server]
port = 8181
hostname = &quot;https://poddown.tatarinovlovesbeaver.su&quot;

[cleanup]
keep_last = 2

[storage]
  [storage.local]
  data_dir = &quot;/mnt/dietpi_userdata/podsync/data&quot;

[tokens]
youtube = &quot;тут ваш ключ из пункта выше&quot;

[feeds]
    [feeds.MaximTatarinov]
    url = &quot;https://www.youtube.com/@MaximTatarinov&quot;
    format = &quot;video&quot;
    update_period = &quot;8h&quot;
    page_size = 5
    youtube_dl_args = [&quot;--js-runtimes&quot;, &quot;deno:/root/.deno/bin/deno&quot;]

[log]
filename = &quot;podsync.log&quot;
max_size = 50
max_age = 30
max_backups = 1
compress = true
debug = false
</pre>
  <p id="MW7H">Конфиг готов.</p>
  <h2 id="запуск-как-systemd-сервис">Запуск как systemd-сервис</h2>
  <p id="b0c1">Чтобы Podsync работал в фоне и запускался автоматически, создаём сервис:</p>
  <pre id="FSD8">nano /etc/systemd/system/podsync.service
</pre>
  <pre id="WNoQ">[Unit]
Description=Podsync
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/mnt/dietpi_userdata/podsync/bin/podsync
WorkingDirectory=/mnt/dietpi_userdata/podsync
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
Environment=&quot;PATH=/root/.deno/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&quot;

[Install]
WantedBy=multi-user.target
</pre>
  <p id="ajdG">Активируем и запускаем:</p>
  <pre id="8h33">systemctl daemon-reload
systemctl enable podsync
systemctl start podsync
</pre>
  <p id="JPEE">Проверить статус:</p>
  <pre id="HBrk">systemctl status podsync
journalctl -u podsync -f
</pre>
  <h2 id="reverse-proxy-через-nginx">Reverse proxy через nginx</h2>
  <p id="EKGa">Podsync у меня работает без TLS, поэтому HTTPS у нас будет обрабатывать nginx. Конфиг для сайта:</p>
  <pre id="YBhW">server {
    listen 80;
    listen [::]:80;
    server_name poddown.tatarinovlovesbeaver.su;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    listen 443 quic;
    listen [::]:443 quic;
    quic_retry on;
    quic_gso on;
    add_header Alt-Svc &#x27;h3=&quot;:443&quot;; ma=86400&#x27; always;

    server_name poddown.tatarinovlovesbeaver.su;

    ssl_certificate /etc/letsencrypt/live/poddown.tatarinovlovesbeaver.su/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/poddown.tatarinovlovesbeaver.su/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://127.0.0.1:8181;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
</pre>
  <p id="sBDX">Применить:</p>
  <pre id="kWA0">nginx -t &amp;&amp; systemctl reload nginx
</pre>
  <h2 id="фильтры-и-тонкая-настройка">Фильтры и тонкая настройка</h2>
  <p id="shWg">Podsync позволяет не просто скачивать всё подряд, а выбирать контент по правилам. Например, скачивать только эпизоды, содержащие «обзор» и длительностью до 2 часов:</p>
  <pre id="ANlH">[feeds]
    [feeds.ID1]
    url = &quot;https://www.youtube.com/@channel&quot;
    format = &quot;audio&quot;
    filters = { title = &quot;обзор&quot;, max_duration = 7200, max_age = 30 }
</pre>
  <p id="cae8">Доступные фильтры:</p>
  <p id="kQBP">Параметр</p>
  <p id="yhPa">Описание</p>
  <p id="Qm25"><code>title</code></p>
  <p id="qdcf">Regex для совпадения в заголовке</p>
  <p id="kOdT"><code>not_title</code></p>
  <p id="636V">Regex для исключения по заголовку</p>
  <p id="wD2V"><code>description</code></p>
  <p id="tgd7">Regex для совпадения в описании</p>
  <p id="ab6m"><code>not_description</code></p>
  <p id="a0Aa">Regex для исключения по описанию</p>
  <p id="IZ99"><code>min_duration</code></p>
  <p id="5KCC">Минимальная длительность (секунды)</p>
  <p id="ORoW"><code>max_duration</code></p>
  <p id="EvTJ">Максимальная длительность (секунды)</p>
  <p id="Ecnz"><code>min_age</code></p>
  <p id="Ei9M">Минимальный возраст (дни)</p>
  <p id="bFNo"><code>max_age</code></p>
  <p id="2Iyo">Максимальный возраст (дни)</p>
  <p id="TOTF">Также можно задать кастомный формат видео:</p>
  <pre id="9DgJ">[feeds]
    [feeds.MaximTatarinov]
    format = &quot;custom&quot;
    custom_format = { youtube_dl_format = &quot;bestaudio[ext=m4a]&quot;, extension = &quot;m4a&quot; }
</pre>
  <h2 id="итог">Итог</h2>
  <p id="G2uO">RSS-лента доступна по адресу:</p>
  <pre id="TewD">https://poddown.tatarinovlovesbeaver.su/MaximTatarinov.xml
</pre>
  <p id="aoWA">Подставляем её в ваш подкаст-клиент и вуаля!</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/obsidiangit</guid><link>https://teletype.in/@beaverclan/obsidiangit?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/obsidiangit?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>Синхронизация заметок Obsidian через GitHub</title><pubDate>Wed, 01 Apr 2026 11:43:54 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/ab/f3/abf312e0-5763-44f8-a3cf-74bda21ae6bd.png"></media:content><category>Blog</category><description><![CDATA[<img src="https://img3.teletype.in/files/2f/41/2f413eaa-a201-4911-ac63-02e9b6ca95ca.png"></img>В условиях турбулентной схемы работы облачных сервисов (скажем это так) вопрос хранения и синхронизации личных заметок приобретает особую актуальность. Данная заметка посвящена настройке синхронизации заметок Obsidian между устройствами iOS (Android пока не пробовал) и MacOS с использованием приватного репозитория GitHub (пока как он ещё работает). Позже дополню с переходом на свой git-сервер, но это решение мне ещё надо обкатать.]]></description><content:encoded><![CDATA[
  <figure id="U1Br" class="m_original">
    <img src="https://img3.teletype.in/files/2f/41/2f413eaa-a201-4911-ac63-02e9b6ca95ca.png" width="800" />
  </figure>
  <p id="0mAI">В условиях турбулентной схемы работы облачных сервисов (скажем это так) вопрос хранения и синхронизации личных заметок приобретает особую актуальность. Данная заметка посвящена настройке синхронизации заметок Obsidian между устройствами iOS (Android пока не пробовал) и MacOS с использованием приватного репозитория GitHub (пока как он ещё работает). Позже дополню с переходом на свой git-сервер, но это решение мне ещё надо обкатать.</p>
  <h2 id="что-у-нас-из-плюсов">Что у нас из плюсов?</h2>
  <ul id="3Lj1">
    <li id="t8Kk">Отсутствие зависимости от iCloud (есть только зависимость от GitHub);</li>
    <li id="lnWK">Бесплатность;</li>
    <li id="79wZ">Автоматическое копирование как содержимого заметок, так и истории их изменений;</li>
    <li id="vIn9">Есть и локальное хранение данных, мы же делаем git pull</li>
  </ul>
  <h2 id="краткое-описание-что-нам-нужно">Краткое описание, что нам нужно</h2>
  <ol id="cefx">
    <li id="YirR">Приватный репозиторий GitHub в качестве центрального хранилища.</li>
    <li id="36WZ">Obsidian собственно.</li>
    <li id="7vlb">Для десктопных платформ: плагин <strong>Git</strong> для Obsidian.</li>
    <li id="N9eL">Для мобильных платформ: плагин <strong>Fit</strong> для Obsidian.</li>
  </ol>
  <h3 id="установка-obsidian-на-устройства">Установка Obsidian на устройства</h3>
  <p id="fSGt">Все ссылки под все платформы:<br /><a href="https://obsidian.md/download" target="_blank">https://obsidian.md/download</a></p>
  <h3 id="создание-приватного-репозитория-на-github">Создание приватного репозитория на GitHub</h3>
  <ol id="XvRO">
    <li id="4AyC">Авторизуйтесь на <a href="https://github.com/" target="_blank">github.com</a>.</li>
    <li id="KtyU">Перейдите по ссылке <a href="https://github.com/new" target="_blank">https://github.com/new</a> и укажите:</li>
    <ul id="3pL1">
      <li id="yNR9">Имя репозитория;</li>
      <li id="wJJo">Тип доступа: <strong>Private</strong>;</li>
      <li id="Z7HL">Опция: <strong>Add a README file</strong> (репозиторий не должен быть пустым).</li>
    </ul>
    <li id="FfeB">Нажмите кнопку создания репозитория.</li>
    <li id="8Lap">В корне репозитория создайте файл <code>.gitignore</code> со следующим содержимым:<code>.obsidian </code></li>
  </ol>
  <p id="0mcp">Файл <code>.gitignore</code> необходим для исключения папки <code>.obsidian</code> из синхронизации. В данной папке хранятся локальные настройки Obsidian, которые могут конфликтовать при синхронизации между разными устройствами.</p>
  <h3 id="создание-токена-доступа">Создание токена доступа</h3>
  <ol id="lPuh">
    <li id="MXWO">Перейдите по ссылке <a href="https://github.com/settings/personal-access-tokens" target="_blank">https://github.com/settings/personal-access-tokens</a>.</li>
    <li id="GBX8">Укажите параметры токена:</li>
    <ul id="USUN">
      <li id="9u7r">Token name (произвольное и понятное вам);</li>
      <li id="LrKn">Expiration: можно <strong>No expiration</strong>, но осторожно;</li>
      <li id="cax8">Repository access: Выберите свой репозиторий, который создали ранее.</li>
      <li id="Ck9r">Permissions: Выберите всё, что связано с репой, без всяких Copilot и пр.</li>
    </ul>
    <li id="CuUU">Создайте токен.</li>
    <li id="L2Ok">Скопируйте и сохраните сгенерированный токен</li>
  </ol>
  <h3 id="настройка-синхронизации-на-десктопной-платформе">Настройка синхронизации на десктопной платформе</h3>
  <h4 id="клонирование-репозитория">Клонирование репозитория</h4>
  <ol id="6rDT">
    <li id="EnI4">Убедитесь, что в системе установлен Git и он настроен</li>
    <li id="br7y">Создайте папку для хранения хранилища Obsidian</li>
    <li id="lKuR">Откройте терминал, перейдите в созданную папку и выполните клонирование:<code>cd ./OBSIDIANREPO git clone git@github.com:username/ObsidianRepo.git </code></li>
  </ol>
  <h4 id="создание-хранилища-в-obsidian">Создание хранилища в Obsidian</h4>
  <ol id="Vtyc">
    <li id="BK3P">Запустите Obsidian.</li>
    <li id="YEwY">Выберите опцию <strong>Open folder as vault</strong> и укажите путь к клонированной папке репозитория.</li>
    <li id="j2ga">Теперь вы можете создавать и редактировать заметки в данном хранилище.</li>
  </ol>
  <h4 id="настройка-плагина-git-для-автоматической-синхронизации">Настройка плагина Git для автоматической синхронизации</h4>
  <ol id="sR9r">
    <li id="gsQX">В настройках Obsidian перейдите в раздел <strong>Community plugins</strong>, отключите <strong>Restricted mode</strong>(если активен), найдите и установите плагин <strong>Git</strong>.</li>
    <li id="Kkv7">В настройках плагина укажите следующие параметры:</li>
  </ol>
  <ul id="nlYc">
    <li id="dsjF">Author name for commit: Ваше имя для коммитов</li>
    <li id="oeRR">Author email for commit: Ваша имя для коммитов Остальные параметры на ваш вкус.</li>
  </ul>
  <h3 id="настройка-синхронизации-на-мобильных-устройствах">Настройка синхронизации на мобильных устройствах</h3>
  <ol id="ngSn">
    <li id="3tMl">Запустите приложение Obsidian на iOS.</li>
    <li id="LEdY">Создайте новое пустое хранилище (не добавляйте в него пока файлы).</li>
    <li id="bRUW">В настройках приложения перейдите в раздел <strong>Community plugins</strong>, найдите и установите плагин <strong>Fit</strong>.</li>
    <li id="sSnw">В настройках плагина укажите:</li>
    <ul id="q8WR">
      <li id="rdLW"><strong>Token</strong>: вставьте Personal Access Token, созданный ранее;</li>
      <li id="WXdW">Нажмите <strong>Authenticate user</strong> (она вверху) для авторизации;</li>
      <li id="Xg8M"><strong>Github repository name</strong>: выберите ваш репозиторий;</li>
      <li id="M5zb"><strong>Branch name</strong>: <code>main</code>;</li>
      <li id="pg7l"><strong>Auto sync</strong>: <code>Muted</code>;</li>
      <li id="dClr"><strong>Auto check interval</strong>: <code>5 minute</code>;</li>
      <li id="GG1u"><strong>File change</strong>: отключите все визуальные уведомления.</li>
    </ul>
  </ol>
  <h3 id="особенности-плагина-fit-и-вообще-всей-связки">Особенности плагина Fit и вообще всей связки</h3>
  <ul id="FcMG">
    <li id="0sX4">Плагин не поддерживает автосинхронизацию при запуске приложения. Для немедленного получения изменений используйте кнопку <strong>Fit Sync</strong> (иконка с котиком в меню бургерном) сразу после запуска Obsidian.</li>
    <li id="x6jw">Не редактируйте один и тот же файл одновременно на двух устройствах, если не умеете разбираться с конфликтами в Git</li>
  </ul>
  <h3 id="итоги">Итоги</h3>
  <p id="hvYT">Ну как-то так.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/navidrome</guid><link>https://teletype.in/@beaverclan/navidrome?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/navidrome?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>Navidrome — свой музыкальный стриминговый сервер на DietPi</title><pubDate>Sat, 07 Mar 2026 15:00:19 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/18/99/1899d154-f7f8-4b3d-8ab9-63d085aba656.png"></media:content><description><![CDATA[<img src="https://blog.tatarinovms.space/images/posts/navidrome/logo.webp"></img>Ввиду недавних извнений на стриминговых платформах, давно хотел иметь свою собственную музыкальную библиотеку, к которой можно получить доступ с любого устройства. У меня конечно уже стоит Jellyfin, но хотелось отдельного решения для музыки. Остановился на Navidrome.]]></description><content:encoded><![CDATA[
  <figure id="qGSL" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/navidrome/logo.webp" width="800" />
  </figure>
  <p id="TIYy">Ввиду недавних изменений на стриминговых платформах, давно хотел иметь свою собственную музыкальную библиотеку, к которой можно получить доступ с любого устройства. У меня конечно уже стоит <a href="https://jellyfin.org/" target="_blank">Jellyfin</a>, но хотелось отдельного решения для музыки. Остановился на <a href="https://www.navidrome.org/" target="_blank">Navidrome</a>.</p>
  <h2 id="почему-navidrome">Почему Navidrome?</h2>
  <p id="6ITB">Navidrome — это лёгкий и быстрый сервер для стриминга музыки с поддержкой Subsonic API. Написан на Go, использует SQLite в качестве базы данных и потребляет минимум ресурсов.</p>
  <p id="sLUZ">Из плюсов:</p>
  <ul id="6Op8">
    <li id="95ja"><strong>Лёгкость</strong> — написан на Go, потребляет мало RAM и CPU</li>
    <li id="G0m7"><strong>Subsonic API</strong> — совместим с большинством клиентов Subsonic</li>
    <li id="SeyU"><strong>Поддержка тегов</strong> — автоматически сканирует и индексирует метаданные</li>
    <li id="FNw7"><strong>Транскодинг</strong> — встроенная поддержка FFmpeg</li>
    <li id="Y69S"><strong>Веб-интерфейс</strong> и <strong>мобильные клиенты</strong></li>
    <li id="yW47"><strong>Мультипользовательский режим</strong> — можно создать аккаунты для семьи</li>
  </ul>
  <h2 id="что-нам-понадобится">Что нам понадобится</h2>
  <ul id="ejyX">
    <li id="7fRl">Сервер с DietPi</li>
    <li id="4yZC">Домен (опционально, для удобного доступа извне)</li>
    <li id="R4t7">Nginx в качестве reverse proxy</li>
  </ul>
  <h2 id="установка-navidrome-на-dietpi">Установка Navidrome на DietPi</h2>
  <h3 id="шаг-1-установка-через-dietpi-software">Шаг 1: Установка через dietpi-software</h3>
  <p id="Y2oq">DietPi имеет встроенную поддержку Navidrome через <code>dietpi-software</code>. Запускаем:</p>
  <pre id="RSuZ">dietpi-software
</pre>
  <p id="hFmp">В меню выбираем <strong>Navidrome</strong>. Мастер автоматически:</p>
  <ul id="sSy9">
    <li id="HxQ5">Установит все зависимости</li>
    <li id="y4tx">Настроит сервис для автозапуска</li>
    <li id="EUoA">Создаст необходимые директории</li>
  </ul>
  <h3 id="шаг-2-настройка-после-установки">Шаг 2: Настройка после установки</h3>
  <p id="Wmhz">После установки Navidrome будет доступен по адресу:</p>
  <pre id="I4Zj">http://&lt;IP-сервера&gt;:4533
</pre>
  <p id="s0wR">Первый созданный пользователь автоматически получит права администратора.</p>
  <h3 id="шаг-3-добавление-музыки">Шаг 3: Добавление музыки</h3>
  <p id="Bn47">По умолчанию Navidrome ищет музыку в директории <code>/mnt/dietpi_userdata/navidrome/music</code>, но в интерфейсе можно будет добавить и свою библиотеку или в конфиге <code>/mnt/dietpi_userdata/navidrome/navidrome.toml</code> поменяйте путь:</p>
  <pre id="Hy6L">MusicFolder = &quot;/mnt/external/music&quot;
</pre>
  <p id="RH7j">на свою папку , она станет вашей основной библиотекой.</p>
  <p id="N4eC">После изменения конфига перезапустите сервис:</p>
  <pre id="RXSe">dietpi-services restart navidrome
</pre>
  <h3 id="шаг-4-проверка-статуса">Шаг 4: Проверка статуса</h3>
  <p id="cqyt">Проверяем что сервис запущен:</p>
  <pre id="ZFJu">dietpi-services status navidrome
</pre>
  <p id="BnlZ">В ответе должно быть <code>active (running)</code>.</p>
  <h2 id="настройка-nginx-в-качестве-reverse-proxy">Настройка Nginx в качестве reverse proxy</h2>
  <p id="bRm1">Если вы хотите использовать доменное имя и HTTPS, нужно настроить reverse proxy. На DietPi это можно сделать через встроенную утилиту.</p>
  <h3 id="шаг-1-устанавливаем-nginx">Шаг 1: Устанавливаем Nginx</h3>
  <pre id="ipqa">dietpi-software
</pre>
  <p id="tdIN">Выбираем <strong>Nginx</strong> для установки.</p>
  <h3 id="шаг-2-получаем-ssl-сертификат">Шаг 2: Получаем SSL сертификат</h3>
  <p id="nX5e">Для настройки HTTPS сначала нужно получить сертификат через встроенную утилиту <code>dietpi-letsencrypt</code>:</p>
  <pre id="dxoq">dietpi-letsencrypt
</pre>
  <p id="7MWL">Следуем инструкциям мастера:</p>
  <ol id="uKMO">
    <li id="msPY">Выбираем домен <code>navidrome.yourdomain.com</code></li>
    <li id="Mi8v">Указываем email для уведомлений</li>
    <li id="Jplh">Выбираем Nginx как веб-сервер</li>
  </ol>
  <p id="m1CP">После успешного выполнения сертификаты будут размещены в <code>/etc/letsencrypt/live/navidrome.yourdomain.com/</code>.</p>
  <h3 id="шаг-3-создаём-конфиг-для-navidrome">Шаг 3: Создаём конфиг для Navidrome</h3>
  <p id="pawP">Создаём файл конфига:</p>
  <pre id="SJ8T">sudo nano /etc/nginx/sites-available/musicstream
</pre>
  <p id="iJFu">С таким содержимым:</p>
  <pre id="flm0">server {
    listen 80;
    listen [::]:80;
    server_name navidrome.yourdomain.com;

    location / {
        proxy_pass http://localhost:4533;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Connection &quot;&quot;;
        proxy_read_timeout 90;
    }

    include /etc/nginx/sites-dietpi/*.conf;

    listen [::]:443 ssl;
    http2 on;
    listen 443 quic;
    listen [::]:443 quic;
    quic_retry on;
    quic_gso on;
    add_header Alt-Svc &#x27;h3=&quot;:443&quot;; ma=86400&#x27; always;

    ssl_certificate /etc/letsencrypt/live/navidrome.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/navidrome.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
</pre>
  <h5 id="пояснения">Пояснения</h5>
  <ul id="eeFC">
    <li id="6V4o"><strong>proxy_pass</strong> — перенаправляем запросы на Navidrome (порт 4533)</li>
    <li id="ebo9"><strong>proxy_set_header</strong> — передаём оригинальные заголовки клиента</li>
    <li id="2of9"><strong>proxy_read_timeout</strong> — увеличиваем таймаут для стриминга</li>
    <li id="t52o"><strong>include /etc/nginx/sites-dietpi/*.conf</strong> — подключаем дополнительные конфиги DietPi</li>
    <li id="RbQ4"><strong>http2 on / quic</strong> — включаем HTTP/2 и HTTP/3 (QUIC) для лучшей производительности</li>
    <li id="AYjz"><strong>Alt-Svc</strong> — заголовок для поддержки HTTP/3</li>
    <li id="hyZu"><strong>ssl_certificate</strong> — пути к сертификатам Let’s Encrypt</li>
  </ul>
  <h3 id="шаг-4-включаем-сайт">Шаг 4: Включаем сайт</h3>
  <pre id="4R0a">sudo ln -s /etc/nginx/sites-available/musicstream /etc/nginx/sites-enabled/musicstream
sudo nginx -t
dietpi-services restart nginx
</pre>
  <p id="rcbc">После перезагрузки Nginx ваш сервер будет доступен по HTTPS с поддержкой HTTP/2 и HTTP/3 (QUIC).</p>
  <p id="7cTL">Также не забудьте открыть порт 443 в вашем фаерволле или роутере.</p>
  <h2 id="клиенты-для-navidrome">Клиенты для Navidrome</h2>
  <p id="Mbas">Navidrome совместим с любым клиентом, поддерживающим Subsonic API. Вот некоторые из них:</p>
  <h3 id="веб">Веб</h3>
  <p id="2MOc">Встроенный веб-интерфейс Navidrome уже имеет полный функционал и адаптивный дизайн. Открыть его можно по адресу:</p>
  <ul id="DcQW">
    <li id="6mhn">Локально: <code>http://&lt;IP-сервера&gt;:4533</code></li>
    <li id="vQzg">Через proxy: <code>https://navidrome.yourdomain.com</code></li>
  </ul>
  <figure id="khqM" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/navidrome/1.webp" width="800" />
  </figure>
  <h3 id="мобильные">Мобильные</h3>
  <p id="nfK9">На телефоне я использую клиент <a href="https://apps.apple.com/app/id6740042497" target="_blank">Yuzic</a></p>
  <figure id="K4YE" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/navidrome/2.webp" width="300" />
  </figure>
  <figure id="PgmL" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/navidrome/3.webp" width="300" />
  </figure>
  <figure id="kSD3" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/navidrome/4.webp" width="300" />
  </figure>
  <h2 id="бекапы">Бекапы</h2>
  <p id="ffIf">Для резервного копирования достаточно сохранить директорию <code>/mnt/dietpi_userdata/navidrome</code>— там находится SQLite база и конфиги</p>
  <h2 id="заключение">Заключение</h2>
  <p id="iCWY">Navidrome — отличное решение для тех, кто хочет иметь свою музыкальную библиотеку с современным интерфейсом и минимальными затратами ресурсов. На DietPi разворачивается за 10 минут, а настройка Nginx proxy позволяет получить безопасный доступ по HTTPS с любого устройства.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/ssh2bwmacos</guid><link>https://teletype.in/@beaverclan/ssh2bwmacos?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/ssh2bwmacos?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>SSH ключи из BitWarden в MacOS</title><pubDate>Mon, 23 Feb 2026 20:27:07 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/6f/ac/6fac502a-1ab6-4f92-a001-a00a799dc159.png"></media:content><description><![CDATA[<img src="https://blog.tatarinovms.space/images/posts/bitwarden-ssh-macos/logo.webp"></img>Долгое время хранил SSH-ключи в виде файлов на диске. Это неудобно и небезопасно: файлы могут быть украдены, забыты на разных устройствах, да и бэкапить их — отдельная головная боль.]]></description><content:encoded><![CDATA[
  <figure id="0bpk" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/bitwarden-ssh-macos/logo.webp" width="800" />
  </figure>
  <h2 id="предыстория">Предыстория</h2>
  <p id="TQId">Долгое время хранил SSH-ключи в виде файлов на диске. Это неудобно и небезопасно: файлы могут быть украдены, забыты на разных устройствах, да и бэкапить их — отдельная головная боль.</p>
  <p id="ElIk">Пользуюсь <a href="https://bitwarden.com/" target="_blank">Bitwarden</a>, а точнее Vaultwarden сервером с десктопным клиентом на компе. Через него храню пароли, TOTP и т.д. Но в Bitwarden можно хранить ещё и SSH-ключи, а встроенный SSH Agent позволяет использовать их без сохранения на диск.</p>
  <h3 id="зачем-это-нужно">Зачем это нужно?</h3>
  <ul id="NdNn">
    <li id="ePc4"><strong>Безопасность</strong> — приватные ключи не лежат в файлах на диске</li>
    <li id="dAGD"><strong>Централизованное хранение</strong> — все ключи в одном месте, с доступом со всех устройств</li>
    <li id="TFyM"><strong>Автоматизация</strong> — SSH сам перебирает ключи, правда Bitwarden не сопоставляет ключи по имени хоста. Он просто предлагает все доступные ключи по очереди. Сервер сам выбирает подходящий.</li>
    <li id="hJJg"><strong>Синхронизация</strong> — добавил ключ в Bitwarden, и он доступен на всех устройствах</li>
  </ul>
  <h2 id="что-понадобится">Что понадобится</h2>
  <ul id="jhPL">
    <li id="lgrS"><a href="https://bitwarden.com/download/" target="_blank">Bitwarden Desktop</a> для macOS. Поставить его можно через Homebrew: <code>brew install bitwarden</code></li>
    <li id="31qx">Немного свободного времени</li>
  </ul>
  <h2 id="шаг-1-включаем-ssh-agent-в-bitwarden">Шаг 1: Включаем SSH Agent в Bitwarden</h2>
  <ol id="atHv">
    <li id="dP56">Открываем <strong>Bitwarden Desktop</strong>приложение</li>
    <li id="2Qbz">Переходим в <strong>Settings → SSH Agent</strong></li>
    <li id="BMfq">Включаем опцию <strong>“Enable SSH Agent”</strong></li>
  </ol>
  <figure id="81y5" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/bitwarden-ssh-macos/1.webp" width="1010" />
  </figure>
  <p id="gZ0W">После включения Bitwarden создаст Unix-сокет для работы с SSH. На macOS путь к сокету:</p>
  <pre id="pJ51">~/.bitwarden-ssh-agent.sock
</pre>
  <h2 id="шаг-2-добавляем-ssh-ключи-в-bitwarden">Шаг 2: Добавляем SSH-ключи в Bitwarden</h2>
  <ol id="9OGL">
    <li id="VAZ0">В Bitwarden создаём новый элемент типа <strong>SSH Key</strong></li>
  </ol>
  <figure id="8k0n" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/bitwarden-ssh-macos/2.webp" width="830" />
  </figure>
  <p id="DTRv">Публичный ключ при этом должен быть добавлен на серверы в <code>~/.ssh/authorized_keys</code> — как обычно.</p>
  <h2 id="шаг-3-настраиваем-окружение">Шаг 3: Настраиваем окружение</h2>
  <p id="Z1Oa">Теперь нужно указать системе использовать сокет Bitwarden вместо стандартного SSH-агента macOS.</p>
  <p id="nYZa">Открываем <code>~/.zshrc</code> и добавляем:</p>
  <pre id="Pjdo">export SSH_AUTH_SOCK=&quot;$HOME/.bitwarden-ssh-agent.sock&quot;
</pre>
  <p id="ZZft">Применяем изменения:</p>
  <pre id="VGAI">source ~/.zshrc
</pre>
  <h2 id="шаг-4-обновляем-ssh-config">Шаг 4: Обновляем SSH config</h2>
  <p id="81re">Открываем <code>~/.ssh/config</code> и убираем <code>IdentityFile</code> (если у вас были уже добавлены, если нет, добавляем с нуля) для хостов, которые будут использовать ключи из Bitwarden.</p>
  <p id="anI6"><strong>Было:</strong></p>
  <pre id="sCBp">Host LinuxServer
    Hostname 192.168.1.11
    user root
    port 22
    IdentityFile ~/LinuxServer.key
</pre>
  <p id="SuUb"><strong>Должно стать:</strong></p>
  <pre id="OGj5">Host LinuxServer
    Hostname 192.168.1.11
    user root
    port 22
    AddKeysToAgent yes
</pre>
  <p id="MWfh">Bitwarden SSH Agent сам предложит все доступные ключи при подключении.</p>
  <h2 id="шаг-5-проверяем-работу">Шаг 5: Проверяем работу</h2>
  <p id="ZnGR">Перед проверкой убедитесь, что <strong>Bitwarden запущен и разблокирован</strong>. Ключи доступны только после разблокировки хранилища.</p>
  <p id="NCc2">Проверяем, что Bitwarden отдал ключи:</p>
  <pre id="lRA9">ssh-add -l
</pre>
  <p id="FCEs">Вывод должен показать ключи из Bitwarden:</p>
  <pre id="LFRD">256 SHA256:i0DqblPzC/00lDAJzetqI53EYzzr+DF@#CDFDF@ LinuxServer (ED25519)
256 SHA256:uFCDz4H6b+dfYb+Od4VilIlOF7FZKCwNA99PgdXdyj0 LinuxServer2 (ED25519)
</pre>
  <p id="XJJo">Подключаемся к серверу:</p>
  <pre id="XHSO">ssh LinuxServer
</pre>
  <p id="x4zc"><strong>Примечание:</strong> После подключения в Bitwarden-клиенте появится запрос на разрешение использования ключа. Но если надоедает это, можно поставить настройку, чтобы не спрашивал, пока не будет заблокировано хранилище.</p>
  <figure id="CzHp" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/bitwarden-ssh-macos/3.webp" width="986" />
  </figure>
  <h2 id="как-это-работает">Как это работает</h2>
  <ol id="Z70W">
    <li id="w3p0"><strong>При подключении SSH</strong> (<code>ssh LinuxServer</code>) сервер отправляет список допустимых ключей</li>
    <li id="MlBv"><strong>Bitwarden SSH Agent</strong> получает запрос и перебирает все разблокированные SSH-ключи</li>
    <li id="WY9M"><strong>Сервер принимает</strong> тот ключ, который есть в <code>~/.ssh/authorized_keys</code></li>
  </ol>
  <p id="JXfU"><strong>Важно:</strong> Bitwarden не сопоставляет ключи по имени хоста. Он просто предлагает все доступные ключи по очереди. Сервер сам выбирает подходящий.</p>
  <h2 id="заключение">Заключение</h2>
  <p id="TEAE">Теперь все SSH-ключи хранятся только в Bitwarden, без файлов на диске. Подключение происходит автоматически, без лишних действий.</p>
  <p id="v4nt">Это безопаснее, удобнее и проще в управлении. Особенно если у вас много ключей для разных серверов.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@beaverclan/flowclip</guid><link>https://teletype.in/@beaverclan/flowclip?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan</link><comments>https://teletype.in/@beaverclan/flowclip?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beaverclan#comments</comments><dc:creator>beaverclan</dc:creator><title>FlowClip - продвинутый менеджер буфера обмена для macOS</title><pubDate>Sat, 24 Jan 2026 21:49:10 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/7d/30/7d30b13d-8b03-4779-ad27-b870d5ee9532.png"></media:content><description><![CDATA[<img src="https://blog.tatarinovms.space/images/posts/flowclip/logo.webp"></img>FlowClip - это менеджер буфера обмена для macOS, созданный как форк проекта Maccy. FlowClip добавляет новую функцию - очередь буфера обмена, которая позволяет собирать несколько элементов и вставлять их вместе.]]></description><content:encoded><![CDATA[
  <figure id="VnyZ" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/flowclip/logo.webp" width="800" />
  </figure>
  <h2 id="что-такое-flowclip">Что такое FlowClip?</h2>
  <p id="lbhN">FlowClip - это менеджер буфера обмена для macOS, созданный как форк проекта Maccy. FlowClip добавляет новую функцию - очередь буфера обмена, которая позволяет собирать несколько элементов и вставлять их вместе.</p>
  <h2 id="основные-возможности">Основные возможности</h2>
  <ul id="9wJg">
    <li id="Z8eG"><strong>Легковесность и скорость</strong>: Минимальное использование ресурсов</li>
    <li id="Ss0M"><strong>Управление с клавиатуры</strong>: Создан для продвинутых пользователей</li>
    <li id="LkwI"><strong>Безопасность и конфиденциальность</strong>: История буфера обмена хранится локально</li>
    <li id="dhpW"><strong>Нативный интерфейс</strong>: Использует стандартные элементы интерфейса macOS</li>
    <li id="bp9U"><strong>Пакетное копирование</strong>: Копируйте несколько элементов последовательно для создания очереди</li>
    <li id="eZrc"><strong>Последовательная вставка</strong>: Вставляйте элементы в том порядке, в котором они были добавлены (FIFO - первый пришел, первый ушел)</li>
    <li id="WalK"><strong>Пользовательские разделители</strong>: Выбирайте, как разделять вставляемые элементы (пробел, новая строка, запятая или пользовательские символы)</li>
    <li id="oGQd"><strong>Визуальная очередь</strong>: Выделенное всплывающее окно для просмотра и управления очередью</li>
  </ul>
  <h2 id="как-использовать-flowclip">Как использовать FlowClip</h2>
  <ol id="z884">
    <li id="WJfR"><strong>Общий доступ</strong>: Нажмите <code>SHIFT + COMMAND + C</code> чтобы открыть FlowClip</li>
    <li id="RGnq"><strong>Режим очереди</strong>:</li>
    <ul id="r9pI">
      <li id="Y6t9">Переключить окно очереди: <code>OPTION + SHIFT + V</code></li>
      <li id="1uoW">Копируйте элементы обычным способом с помощью <code>COMMAND + C</code> пока активен режим очереди</li>
      <li id="fenl">Используйте окно очереди для управления или очистки элементов</li>
    </ul>
    <li id="U4a2"><strong>Выбор и вставка</strong>:</li>
    <ul id="pR3p">
      <li id="qPq5">Введите текст для поиска по истории буфера обмена</li>
      <li id="Jaoe"><code>ENTER</code> чтобы скопировать выбранный элемент</li>
      <li id="oZGW"><code>OPTION + ENTER</code> чтобы вставить напрямую</li>
    </ul>
  </ol>
  <figure id="Ah0F" class="m_original">
    <img src="https://blog.tatarinovms.space/images/posts/flowclip/2.webp" width="700" />
  </figure>
  <h2 id="как-установить-flowclip">Как установить FlowClip?</h2>
  <pre id="iVRv">brew tap gityeop/flowclip
brew install --cask flowclip</pre>

]]></content:encoded></item></channel></rss>