Skip to content

Instantly share code, notes, and snippets.

@drslump
Created August 18, 2025 11:42
Show Gist options
  • Select an option

  • Save drslump/399193a4f9d2e2a1c1b94d0b32c9cdeb to your computer and use it in GitHub Desktop.

Select an option

Save drslump/399193a4f9d2e2a1c1b94d0b32c9cdeb to your computer and use it in GitHub Desktop.
Convert w3u playlist to m3u format
#!/usr/bin/env node
import { readFileSync} from 'fs'
const [, , w3uFile] = process.argv
if (!w3uFile) {
console.error('Usage: w3u-to-m3u <input.w3u>')
process.exit(1)
}
const w3uContent = readFileSync(w3uFile, 'utf8')
const w3u = JSON.parse(w3uContent)
console.log('#EXTM3U url-tvg="https://raw.githubusercontent.com/davidmuma/EPG_dobleM/refs/heads/master/guiatv.xml, https://epgshare01.online/epgshare01/epg_ripper_NL1.xml.gz"')
console.log('#EXTVLCOPT:network-caching=1000')
const nameDelimiters = /\s(HD|FHD|UHD|SD|1080|720|[^\w\s+])/g;
w3u.groups
.filter((group) => group.stations !== undefined)
.forEach((group) => {
group.stations.forEach((station) => {
const { name } = station
const nameParts = name.split(nameDelimiters)
const sanitizedId = nameParts[0]?.trim()
.replace(/\b(M\.|Movistar) /gi, 'M+ ')
.replace(/\bDazn\b/gi, 'DAZN')
.replace(/\bLa\s?Liga/gi, 'LaLiga')
.replace(/^Liga de Campeones/i, 'M+ Liga de Campeones')
// VLC parses the hyphen as a tuple of author - title
const sanitizedName = name.replace(' - ', ' -- ')
console.log(`#EXTINF:-1 group-title="${group.name}" tvg-logo="${station.image ?? group.image}" tvg-id="${sanitizedId}", ${sanitizedName}`)
if (station.url.startsWith('acestream://')) {
console.log('https://ace.velencoso.cat/' + station.url.slice(12))
} else {
console.log(station.url)
}
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment