MyGo 云音乐
Go와 MyGo로 만든 서드파티 네이버 클라우드 뮤직 데스크톱 클라이언트
이미지·영상·오디오 파일을 온라인에서 변환·편집·압축·전사·요약·검사
Convert, edit, compress, transcribe, summarize, and inspect image, video, and audio files online with Media Manipulator.
미디어TypeScript · JavaScriptGitHub @mrrobotisreal온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기The UI for the Media Manipulator web app
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗The free, no‑signup web app for converting, compressing, editing, transcribing, and cleaning up image, video, and audio files — including Content Studio, a multi‑track video editor that runs right in your browser.
This repository is the frontend for media-manipulator.com: a Next.js (App Router) application that renders the marketing/SEO surface as static HTML and hosts the interactive conversion and editing tools as client‑side islands. Heavy media processing happens on a dedicated backend; this app orchestrates uploads, job polling, and downloads, and presents everything behind a fast, crawlable, ad‑safe UI.
TOOL_PAGES in content/toolPages.ts: 112 pages, of which 14 are thin alias pages for duplicate‑intent slugs that canonicalise to their primary, content/toolAliases.ts) across image, video, audio, AI, and privacy/metadata categories, each with a unique landing page. The 24 allowlisted and pending pages meet the MM84 copy bar (content/toolCopy.test.ts).i18next / react-i18next with feature‑sharded locale bundles.npm run audit:ads) blocks regressions.| Category | Examples | Notes |
|---|---|---|
| Image | Convert (JPG/PNG/WebP/AVIF/GIF/SVG/ICO), compress, resize, crop, remove background, image→PDF | Server‑side ImageMagick; AI background removal on a GPU server |
| Video | Convert (MP4/MOV/WebM/MKV/AVI…), compress, trim/cut, crop, rotate, →GIF, extract/remove audio, transcode to HLS/DASH | FFmpeg pipeline; large files use presigned S3 uploads |
| Audio | Convert (MP3/WAV/AAC…), waveform generator, isolate vocals | AI stem separation on a GPU server |
| AI | Transcribe video/audio, SRT generator, caption translator, AI frame interpolation | Models run on a local GPU server we operate |
| AI Video Restoration | Restore/upscale a ≤15s snippet with up to six models (Real‑ESRGAN, SwinIR, HAT, BasicVSR++, RVRT, VRT) and download one comparison package | /tools/ai-video-restoration; snippet selector + multi‑model pipeline on our GPU server |
| Privacy | Remove EXIF/GPS/IPTC/XMP metadata | Strips location & device data before sharing |
| Content Studio | Multi‑track editor → MP4 | See Content Studio |
Plus content sections: Tutorials (getting‑started guides + AI frame interpolation + Content Studio) and a Blog (compression, optimization, and audio‑quality guides).
The frontend is a thin, fast orchestration layer. It never does heavy media work itself — it requests uploads, tracks jobs, and serves results, while the backend API does the actual transcoding/AI.
flowchart LR
U([User]) -->|HTML / RSC| FE["Next.js App Router<br/>(this repo, on Vercel)"]
FE -->|"static pages, metadata, JSON-LD"| U
FE -->|"upload / poll / download (REST)"| API["Media API<br/>api.media-manipulator.com"]
FE -->|"large files (PUT)"| S3[("Object storage<br/>presigned S3")]
API --> S3
API -->|"FFmpeg / ImageMagick"| WORK["Processing workers"]
API -->|"transcribe, interpolate,<br/>bg-removal, vocal isolation"| GPU["Local GPU server"]
FE -. "consent-gated" .-> AN["Analytics<br/>first-party (MM Analytics) · slim GA4 cross-check"]
Rendering model
"use client") power anything interactive: file inputs, drag‑and‑drop, the converter forms, and the Content Studio editor. Browser‑only/editor surfaces are loaded with next/dynamic({ ssr: false }) so they never run during prerender — yet the SEO copy around them is always server‑rendered.lib/metadata.ts) and server‑rendered JSON‑LD (components/seo/json-ld.tsx) — never mutated on the client.sequenceDiagram
actor User
participant UI as Web UI
participant API as Media API
User->>UI: Drop a file + pick options
UI->>API: POST /upload (multipart) + options
API-->>UI: { jobId }
loop every 2s until done
UI->>API: GET /job/{jobId}
API-->>UI: { status, progress }
end
UI->>API: GET /download/{jobId}
API-->>UI: Converted file (Blob)
UI-->>User: Preview + download
sequenceDiagram
actor User
participant UI as Web UI
participant API as Media API
participant S3 as Object storage
User->>UI: Drop a video + pick options
Note over UI: phase: requesting-url
UI->>API: POST /video-upload/presign
API-->>UI: { uploadUrl, key }
Note over UI: phase: uploading-to-s3
UI->>S3: PUT file (direct upload)
Note over UI: phase: finalizing
UI->>API: POST /video-upload/complete (key + options)
API-->>UI: { jobId }
loop every 2s
UI->>API: GET /job/{jobId}
API-->>UI: { status, progress }
end
UI->>API: GET /download/{jobId}
UI-->>User: Result
The same upload→poll→download lifecycle powers convert, transcribe, and transcode (HLS/DASH) workflows — they differ only in the options payload and how the result is rendered (file download, transcript view, or streaming manifest).
flowchart TD
drop([File dropped / selected]) --> detect{Detect media kind}
detect -->|image| img[Image conversion form]
detect -->|video| vmode{Workflow}
detect -->|audio| amode{Workflow}
detect -->|pdf| pdf[PDF tools]
vmode -->|convert| vconv[Video conversion form]
vmode -->|transcribe| vtr[Transcribe form]
vmode -->|transcode| vtc[HLS/DASH transcode form]
amode -->|convert| aconv[Audio conversion form]
amode -->|transcribe| atr[Transcribe form]
Content Studio (/tools/content-studio) is the flagship tool: a browser‑based, multi‑track video editor.
flowchart LR
new([Create project<br/>resolution + fps]) --> bin[Import media<br/>video / image / audio]
bin --> tl[Multi-track timeline]
tl --> edit[Trim · split · ripple-delete]
edit --> layer[Layer overlays · titles · audio mix]
layer --> prev[Live preview<br/>canvas compositing]
prev --> exp[[Export → MP4<br/>H.264 / AAC]]
This app is built to pass Google AdSense review cleanly:
NEXT_PUBLIC_ADSENSE_ENABLED=true and NODE_ENV=production and the page/placement/slot pass the guards in lib/adsenseConfig.ts./tools/<slug> pages, placed after substantial copy and far from action buttons. No header/footer/sidebar/anchor/post‑conversion ads, no side rails, no sticky units.data-ad-slot.components/mock-ad.tsx) are local‑preview‑only and never contact Google.content/reviewAllowlist.ts) drives which tools are indexed, listed, sitemapped, and ad‑eligible. The homepage and review pages never link into non‑allowlisted tools.components/ads/adsense-loader.tsx loads Google's script from the layout on ad‑eligible pages (isAdEligiblePath), after the Consent Mode defaults (all ad signals denied); units show to anonymous and free visitors only.npm run audit:ads fails the build on any regression (placeholder leakage, ad script outside the config/loader, disallowed placements, macOS artifacts, the loader or a unit on ineligible pages, an ads‑on build with no loader + slot on the tool pages, the home/tool pages linking to non‑allowlisted tools, /tools or home linking a non‑allowlisted, non‑pending tool without rel="nofollow" (MM84), or any page linking an alias slug from content/toolAliases.ts). It reads .next/server/app/en.html + en/**/*.html and fails if a build exists but no English HTML is found.app/sitemap.ts) + crawler‑friendly app/robots.ts, with canonical origin https://www.media-manipulator.com..
├── app/ # Next.js App Router (routes, layout, sitemap, robots)
│ ├── tools/ # /tools, /tools/[slug], /tools/content-studio
│ ├── blog/ · tutorials/ # content routes (server-rendered)
│ ├── layout.tsx # root layout, GA consent bootstrap, fonts
│ ├── providers.tsx # client providers + route analytics + shell
│ ├── sitemap.ts · robots.ts
│ └── globals.css # Tailwind v4 + theme tokens + custom CSS
├── components/ # UI components
│ ├── content-studio/ # the multi-track editor
│ ├── tools/ # server-rendered tool landing page + panel island
│ ├── seo/ # JSON-LD renderer
│ ├── ui/ # Radix-based primitives
│ ├── ad-banner.tsx · mock-ad.tsx
│ └── top-nav.tsx · footer.tsx · ...
├── views/ # Page-level client views (home, about, blog, tutorials…)
├── content/ # toolPages.ts (tool data), reviewAllowlist.ts, keywordMap.ts
├── lib/ # hooks + logic: upload/convert/transcode, firebase (lazy),
│ # analytics, adsenseConfig, adSlots, seo, metadata, studio…
├── i18n/ # i18next setup + sharded en-US locale bundles
├── schemas/ # zod schemas for conversion options
├── scripts/ # audit-adsense.mjs, clean-appledouble.mjs
├── docs/ # adsense review plan + slot inventory
└── public/ # fonts, icons, ads.txt, og image
Prerequisites: Node.js ≥ 20 and npm.
# 1. Install dependencies
npm ci
# 2. Configure environment
cp .env.example .env.local # then fill in values (see below)
# 3. Run the dev server
npm run dev # http://localhost:3000
The app builds and runs without Firebase credentials — Firebase initializes lazily and only in the browser, so public pages prerender fine with blank
NEXT_PUBLIC_FB_*values. Accounts/auth simply stay disabled until configured.
All browser‑exposed variables use the NEXT_PUBLIC_ prefix. See .env.example for the full template.
| Variable | Purpose | Default if unset |
|---|---|---|
NEXT_PUBLIC_API_BASE_URL | Media API base URL | https://api.media-manipulator.com/api |
NEXT_PUBLIC_ANALYTICS_BASE_URL | First‑party analytics endpoint | https://analytics.media-manipulator.com |
NEXT_PUBLIC_ANALYTICS_WRITE_KEY | Required. Public site key for /v1/capture; must match a WRITE_KEYS entry on the analytics service. Not a secret — it ships in the bundle. | — (capture returns 401) |
NEXT_PUBLIC_GA_MEASUREMENT_ID | GA4 measurement ID. Slim cross‑check only (3 events). | G-6J910CMHRY |
NEXT_PUBLIC_FB_* | Firebase web config (auth only) | — (auth disabled if blank) |
NEXT_PUBLIC_ADSENSE_ENABLED | Enable real AdSense (prod only) | false |
NEXT_PUBLIC_MOCK_ADS_ENABLED | Show first‑party mock ads (dev only) | false |
Set only as branch-scoped Vercel Preview variables on a translate/<prefix> branch, never on Production. scripts/vercel-translator-env.sh sets them for all 17 branches from your shell (run --dry-run first; it reads the secrets from your environment and never prints them). The design is in ../docs/design/TRANSLATOR_WORKBENCH.md; the setup checklist is MM55.
| Variable | Scope | Purpose |
|---|---|---|
NEXT_PUBLIC_DEPLOY_ROLE | build | translator turns on translator mode (hardening; app/api/translator/* answer 404 without it) |
NEXT_PUBLIC_TRANSLATOR_LOCALE | build | The edited locale, e.g. de-DE (node scripts/list-locales.mjs --codes) |
TRANSLATOR_EMAILS | server | Comma-separated allowlist (trimmed, case-insensitive; empty = nobody) |
GITHUB_APP_ID | server | The "Media Manipulator Translator" GitHub App id |
GITHUB_APP_INSTALLATION_ID | server | Its installation on this repo |
GITHUB_APP_PRIVATE_KEY | server, sensitive | The App's private key PEM, base64-encoded |
GITHUB_REPO | server | mrrobotisreal/media_manipulator_ui |
GITHUB_BASE_BRANCH | server | main (PR base and conflict reference) |
NEXT_PUBLIC_FB_PROJECT_ID | build | Already set for auth; also the issuer/audience for ID-token checks |
GitHub Actions secrets for .github/workflows/sync-translate-branches.yml: VERCEL_TOKEN (a Vercel access token), VERCEL_PROJECT_ID, and VERCEL_TEAM_ID when the project belongs to a team. The workflow creates each translate/<prefix> Preview deployment through POST /v13/deployments, because Vercel does not build branches pushed by a GitHub Actions bot and Deploy Hooks are capped at 5 per project. Missing secrets are a notice, not a failure. TRANSLATE_SYNC_TOKEN is optional: a fine-grained token with Contents + Workflows write, used only if GitHub refuses a GITHUB_TOKEN push of commits that change workflow files.
Translator routes (Node runtime, Cache-Control: no-store, 404 off-role): GET /api/translator/me, GET /api/translator/base, POST /api/translator/submit[?dryRun=1]. The contract is in lib/translator/submitContract.ts and lib/translator/server/handlers.ts.
| Script | What it does |
|---|---|
npm run dev | Start the Next dev server |
npm run build | Production build (static generation) |
npm run start | Serve the production build |
npm run lint | ESLint |
npm run typecheck | tsc --noEmit |
npm run audit:ads | AdSense‑review safety audit (run after build for link checks) |
npm run clean:macos-artifacts | Remove stray .DS_Store / ._* files |
Pre‑push checklist: npm run typecheck && npm run lint && npm run build && npm run audit:ads — all should pass.
Deployed on Vercel (zero‑config Next.js). Set the NEXT_PUBLIC_* variables in the Vercel project settings; for the AdSense review keep NEXT_PUBLIC_ADSENSE_ENABLED=false and NEXT_PUBLIC_MOCK_ADS_ENABLED=false. ads.txt, the sitemap, and robots are served automatically.
Translations live in i18n/locales/<locale>/<namespace>/*.json, sharded by feature (interface, forms, panels, pages, components, accessibility, error). useLocalization() wraps react-i18next and adds locale‑aware date/number/file‑size/duration formatters. Resources are bundled inline so server‑prerendered HTML contains real translated text (good for SEO). Add a language by adding its row to i18n/locales.ts, copying i18n/locales/en-us/ to i18n/locales/<code-lowercased>/ (without the English-only interface/metadata.json) and running npm run i18n:gen. Only English is bundled into client JS; other locales reach the client through the [lang] layout. node scripts/list-locales.mjs prints the non-English prefixes for scripts and workflows.
Uploads are processed on our own servers and are designed to be automatically deleted within 24 hours. AI features run on a GPU server we operate; files are not shared with third‑party AI providers. No account is required to use the tools. Analytics are first-party (our own MM Analytics service) with a slim GA4 cross-check, and are consent‑gated — Google Consent Mode v2 mirrors our own consent state rather than the other way round. Mixpanel and Firebase Analytics were removed in Part 1.
This project is released under a proprietary license — see LICENSE. The source is published for demonstration and portfolio review; commercial use, redistribution, and hosting are not permitted without prior written permission.
Author: Mitchell Wintrow Email: [email protected] Website: https://www.media-manipulator.com
© 2026 Media Manipulator, a CreaTV Ltd. product. All rights reserved.