Provider Guide
Publish your own channels for NOCPlayer users. All it takes is a JSON file on your server — no SDK, no account, no approval needed.
What is a Provider?
A provider is any website or developer that hosts a NOCPlayer-compatible JSON file (a "channel pack"). Users import your pack URL directly into the app and immediately see your channels alongside the default ones.
Providers have full control over what channels they publish and how they look. There's no approval process — if your JSON is valid, it works.
Getting Started
To publish a channel pack:
- Create a JSON file matching the pack file schema below.
- Host it at any public HTTPS URL, e.g.
https://yoursite.com/nocplayer/pack.json - Make sure your server returns
Content-Type: application/jsonand allows cross-origin requests (Access-Control-Allow-Origin: *). - Share the URL with your users — they paste it into NOCPlayer under My Channels → Import from URL.
Access-Control-Allow-Origin: *, the import will fail on Android and the web.
Pack File
The top-level JSON file that describes your provider, categories, and channels.
JSON{ "schema_version": "1.0", "id": "my-provider-pack", "name": { "en": "My Channels", "vi": "Kênh Của Tôi" }, "description": { "en": "Curated video channels" }, "image": { "url": "https://yoursite.com/cover.png", "type": "cover" }, "color": "#1a1a2e", "author": "yoursite", "updated_at": "2025-04-01", "categories": [ { "id": "movies", "name": { "en": "Movies" }, "image_type": "cover" } ], "channels": [] }
| Field | Type | Required | Notes |
|---|---|---|---|
| schema_version | string | required | Always "1.0" |
| id | string | required | Unique slug, no spaces |
| name | object | required | Locale map — at minimum include "en" |
| description | object | optional | Locale map |
| image | object | optional | url + type ("cover" = 16:9) |
| color | string | optional | Hex color used as accent in the app |
| author | string | optional | Your name or handle |
| updated_at | string | optional | ISO date, YYYY-MM-DD |
| categories | array | optional | See below |
| channels | array | required | Array of channel objects |
Category object
| Field | Type | Notes |
|---|---|---|
| id | string | Unique slug. Referenced by channels via category_id |
| name | object | Locale map |
| image_type | string | "cover" (16:9), "poster" (2:3), or "square" (1:1) |
Stream Channel
A channel with a single direct stream URL (M3U8, MP4, or iframe).
JSON{ "id": "big-buck-bunny", "name": { "en": "Big Buck Bunny" }, "description": { "en": "Blender Foundation open film" }, "image": { "url": "https://…/cover.jpg", "type": "cover" }, "category_id": "shorts", "type": "stream", "stream": { "url": "https://example.com/video.m3u8", "type": "m3u8", "fallback_url": "https://example.com/video.mp4" }, "source": "imported", "added_at": "2025-04-01" }
| stream field | Type | Notes |
|---|---|---|
| url | string | required — the primary stream URL |
| type | string | optional — "m3u8", "mp4", or "iframe". Auto-detected from URL extension if absent. |
| fallback_url | string | optional — tried if the primary URL fails |
Multi-stream: Episodes & Servers
When a channel has multiple episodes or mirror servers, use the streams[] array instead of stream. The app shows a chip row below the player so users can switch between them.
JSON{ "id": "my-series", "name": { "en": "My Series" }, "type": "stream", "streams": [ { "label": "Episode 1", "url": "https://embed.example.com/ep1" }, { "label": "Episode 2", "url": "https://embed.example.com/ep2" }, { "label": "1000", "url": "https://embed.example.com/ep1000" } ] }
For mirror servers, the same shape applies — just use different labels:
JSON"streams": [ { "label": "Server 1", "url": "https://…" }, { "label": "Server HD", "url": "https://…" }, { "label": "2", "url": "https://…" } ]
streams[] items are always played in iframe mode. The player will not attempt HLS or native playback. Labels are displayed exactly as written — string or number, no transformation.
Picker UI behaviour
- 1–20 streams: chips shown directly below the player
- 21+ streams: page bracket buttons appear above the chips (
1–20,21–40, …). Clicking a bracket shows that page's chips. - Selecting a chip swaps the iframe URL without any page navigation.
- The first item in the array is loaded by default.
Playlist Channel
A playlist channel points to API endpoints that return video lists and search results. This allows large dynamic libraries without embedding all videos in the pack file.
JSON{ "id": "my-library", "name": { "en": "My Video Library" }, "type": "playlist", "endpoints": { "list": "https://yoursite.com/api/videos.json", "search": "https://yoursite.com/api/search.json" }, "source": "imported", "added_at": "2025-04-01" }
endpoints.search is absent, the search UI is hidden for that channel. The app always calls the endpoint — it never filters locally.
Iframe Channel
Use "type": "iframe" inside the stream object to force iframe embed mode. No progress bar, skip buttons, quality picker, or ads are shown.
JSON{ "id": "embedded-player", "name": { "en": "Embedded Player" }, "type": "stream", "stream": { "url": "https://some-embed.com/player/123", "type": "iframe" } }
Video Object
Returned inside playlist list and search endpoint responses.
JSON{ "id": "video-001", "title": { "en": "My Video Title" }, "description": { "en": "A short description" }, "thumbnail": "https://…/thumb.jpg", "duration": 142, "stream": { "url": "https://example.com/video.m3u8", "type": "m3u8", "fallback_url": "https://example.com/video.mp4" }, "added_at": "2025-04-01" }
Videos can also use streams[] for multiple servers or episodes — the same shape as channel multi-stream.
Pagination Envelope
All list and search endpoint responses must be wrapped in this envelope.
JSON{ "items": [ /* array of video objects */ ], "pagination": { "current_page": 1, "per_page": 20, "total": 340, "has_more": true }, "query": "moon" // search responses only }
Field Reference
| Field | Values | Notes |
|---|---|---|
| image.type | "cover" "poster" "square" | 16:9, 2:3, 1:1. Default: "cover" |
| stream.type | "m3u8" "mp4" "iframe" | Auto-detected from URL if absent; unknown extensions fall through to iframe |
| category_id | string or null | null → channel appears in "Featured" row |
| source | "default" "user" "imported" | Use "imported" for provider packs |
| streams[].label | string or number | Displayed as-is. No transformation applied. |
| ads.skip_after | integer (seconds) | Default: 5 if absent. Ads not supported on iframe channels. |
Example Files
The NOCPlayer default pack is a live example you can inspect:
- nocplayer.com/channels/default.json — Default pack (6 channels)
Provider Directory
Sites listed here are independent providers that publish NOCPlayer-compatible channel packs. Each one links back to nocplayer.com — that's the only condition for being listed.
No providers listed yet.
Be the first — see "Get Listed" below.
Get Listed
Want your site in the directory? Here's how it works:
- It's free. There is no charge to be listed.
- Link back required. You must display a visible link to
nocplayer.comon your site — on your homepage, a footer, or a dedicated page. Removing the link will remove your listing. - Your choice. Participation is entirely optional. You can use NOCPlayer's format and distribute your pack without being listed.
- Content responsibility. You are responsible for the content in your channel pack. Illegal or harmful content will result in immediate removal.
Submit your site
Send the following details to be reviewed for the directory. Listings are added manually — please allow a few days.
The public HTTPS URL of your channel pack JSON file.
Or talk to us directly at telegram: @nocplayer with the same details.