尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗neomosh is a video recorder in one standalone HTML file. It makes a true datamosh: it has its own H.264 encoder and decoder. When you pause and resume, the new clip has no keyframe. The P-frames of the new clip move the pixels of the last picture of the previous clip.
The exported file is a valid H.264 (Constrained Baseline) stream. Each conforming player shows the same moshed pictures.
Status: v0.5.0. All phases are done: codec, MP4 export, recorder, history, file source, settings, and Upscale export. neomosh records video only (no audio). See
neomosh-plan-v0.1.0.md.
Put dist/neomosh-v0.5.0.html on a web server with HTTPS (for example GitHub Pages), or open it on localhost. Browsers refuse camera access on plain HTTP. Safari also refuses it on a local file:// page.
Touch Start and give permission to the camera. When the phone has more than one rear camera, chips at the bottom of the view (for example 0.5×, 1×, Tele, or 1, 2, 3) select one, before a clip or while paused. When the camera can zoom, pinch the view with two fingers (also while recording); the chip with the level (for example 2.5×) goes back to 1× when you touch it.
Touch the red button to record. The view shows the decoded output of the encoder.
Touch the button again to pause. The last picture shows above the live camera. Move the Guide slider to change its opacity, and align the next shot.
Touch the red button to resume. The new clip has no keyframe, so its motion moves the old picture. This is the datamosh. The mosh needs movement: if nothing moves, the old picture stays frozen.
Repeat steps 4 and 5 as many times as necessary.
Bloom: while paused, hold the BLOOM button (next to the red button, or the B key). The motion at the end of the last clip repeats, so the picture keeps flowing and smearing in that direction. Release it to end the bloom: it is a clip of its own, with a pause point. The bloomed picture stays, and the next clip moshes on from it.
To use a video file as the source (at the start or at any pause point), touch FILE and select a file. The File slider below the view sets the start point. For an MP4 or MOV file, the app decodes each frame of the file at the speed of the device, not in real time, so no frame is dropped: the view shows the moshed frames as they are made, and the export has the true speed of the file. Other files (for example WebM) play at normal speed while you record. The recording pauses with the file. At the end of the file, the recording pauses. Touch FILE again to select a different file, or CAMERA to go back to the camera. A file is never mirrored. The sound of the file is not recorded. If the camera is not available, the start screen offers Use a video file.
To go back, touch the thumbnail (bottom left) while paused. The History sheet plays the video and shows one card for each pause point. Touch a card, then Revert, to delete all clips after that point and continue from it. Start deletes all clips. New video deletes the video.
Touch Export (top right). For each cut, select Mosh or Clean. Touch Export, then Save Video (iOS) or Download.
Original mode (the default) copies the recorded frames into the file. It is fast and lossless. Upscale mode scales the video to 1080 on the short side (Sharp keeps the blocks, Smooth blurs them) and encodes it again with the H.264 encoder of the browser. Upscale shows only when the browser has an H.264 encoder.
An amber badge shows the count of frames that the encoder dropped. Touch it for help.
Touch the gear (top left).
| Setting | Values | Default | When it can change |
|---|---|---|---|
| Size (short side) | 360, 480, 720, 1080 | 480 | Before the first recorded frame. 720 and 1080 need a fast device |
| Frame rate | 15, 24, 30 | 30 | Before the first recorded frame. A hint shows when the device is too slow for the rate |
| Shape | 1:1, 4:3, 3:2, 16:9; vertical or horizontal | 4:3, from the screen | Before the first recorded frame (bar above the view) |
| Quality (QP) | 16–44 | 30 | While paused. High = coarse blocks; low = clean detail, larger file |
| Search range | ±8, ±16, ±32, ±64 | ±32 | While paused. Larger = longer smears with fast motion, more CPU |
| Motion | Full, Half, Quarter | Quarter | While paused. Full = blocky steps; Quarter = smooth flowing smear |
| Skip bias | 0–100 | 50 | While paused. High = more old pixels stay |
| Heal | Off, Low, High | Low | While paused. Low and High repair bad areas (partial mosh) |
| Denoise | Off, Low, High | Low | While paused. Removes sensor noise before the encoder: faster and smaller with a noisy camera (for example a second rear camera), a little smoother picture |
| Mosh preview | On, Off | On | At any time. Off shows the raw source while recording |
| Mirror front camera | On, Off | On | At any time. Applies to the next clip |
| Theme | Default (green and pink, an animated orb record button), OS (yellow and red), Contrast (white, outlines), Night (soft warm colours) | Default | At any time. Only the look of the app, not the video |
The encoder settings apply to the next clip. Each clip keeps its own look. A revert also restores the settings of that pause point. Default look sets the encoder settings to their defaults. The Info section at the bottom (closed at first) shows the dropped frames, the storage used and free, and how this browser records. When the device is too slow for the selected size and frame rate, it shows a warning; the warning comes only after the first clip, when the speed is measured. Open the page with #debug for the details and the self-test.
| Browser | Status |
|---|---|
| Chrome (Android, desktop) | Tested. Upscale export is available |
| Edge | Same engine as Chrome. Not tested |
| Safari (iOS 16.4 or later, macOS) | Must work. Not tested yet (plan §13.4). Upscale export when Safari has an H.264 VideoEncoder |
| Firefox 132 or later | Must work. Not tested |
The browser must have WebAssembly SIMD for full speed. Without it, the codec uses JavaScript, which is approximately 10 times slower. The page makes no network requests.
For a check of a device, open the page with #debug at the end of the address. The settings sheet then shows Run the self-test. It exports the video, decodes it with the decoder of the browser, and compares each frame with the neomosh decoder. The result must be "PASS. Identical".
The app keeps the video in the browser storage (IndexedDB). When you open the app again, touch Continue last video to continue from the last pause point, or Start new. If the app closed during a recording, it keeps the frames that were stored (all but about the last second) and makes a new pause point.
Requirements: Node.js 20 or later. FFmpeg and ffprobe for the tests.
| Command | Result |
|---|---|
node tools/build.mjs | Makes dist/neomosh-v0.5.0.html and dist/neomosh-bench-v0.5.0.html, and copies the app to index.html (the page for GitHub Pages) |
node tools/build-wasm.mjs | Compiles src/codec/wasm/kernels.c to WebAssembly (needs clang with the wasm32 target). Only after a change to the C code: the compiled module is in the repository |
node tests/run.mjs [filter] | Runs the tests. Output files go to tests/out/ |
node tools/bench.mjs [frames] | Runs the encoder benchmark in Node |
node tools/sample.mjs | Makes sample MP4 files in samples/ for device tests |
node tools/build.mjs.dist/neomosh-bench-v0.5.0.html to the phone (for example with AirDrop or Files), or serve it from a local web server.The page makes no network requests. The encoder p95 time must be below the frame budget: 33.3 ms at 30 fps, 41.7 ms at 24 fps, 66.7 ms at 15 fps.
The tests encode synthetic video, write an Annex B .264 file and an .mp4 file, and decode them with FFmpeg. The FFmpeg output must be byte-identical to the output of our decoder (plan §13.1). The MP4 packets must have the correct times, durations, and sync flags. When Playwright is installed, a test also decodes the MP4 samples with the Chromium WebCodecs decoder and plays the files in a <video> element, and tests operate the built app with a fake camera: record, pause, resume, history, settings, storage full, Original and Upscale export, and the self-test. The mosh test (plan §13.2) makes sure that, after a cut, only the area along the motion path changes.
| Path | Contents |
|---|---|
src/codec/ | H.264 subset: bit I/O, tables, transform, interpolation, motion vector prediction, CAVLC, headers, colour, encoder, decoder |
src/codec/wasm/ | The computation-intensive parts of the codec in C, compiled to WebAssembly with SIMD. The JavaScript functions are the fallback and the reference; the tests prove that both give the same bits |
src/bench/ | Benchmark page and core |
src/app/ | App: user interface (based on neocamera v1.5.0), recorder, workers (capture, encoder, decoder), storage, Upscale export, self-test |
src/mux/ | MP4 muxer and lossless export (remux) |
tools/build.mjs | Inlines all sources into one HTML file for each page |
tests/ | Node tests |
dist/ | Built files |