[{"data":1,"prerenderedAt":977},["ShallowReactive",2],{"page:\u002Farticles\u002Fintroducing-teleconvert":3},{"id":4,"title":5,"author":6,"body":10,"cover":964,"date":965,"description":966,"extension":967,"head":968,"layout":971,"meta":972,"navigation":368,"path":973,"seo":974,"stem":975,"__hash__":976},"pages\u002Farticles\u002F9.introducing-teleconvert.md","Introducing TeleConvert",{"name":7,"avatarUrl":8,"link":9},"Likun Cai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F103620968?v=4","https:\u002F\u002Fgithub.com\u002FAlchemist-Aloha",{"type":11,"value":12,"toc":953},"minimark",[13,18,22,38,41,46,49,59,69,80,84,87,118,131,144,147,216,219,270,274,277,300,303,329,332,336,339,345,348,503,515,525,529,532,582,597,600,717,723,727,730,736,739,811,819,823,826,852,855,859,928,932,935,938,949],[14,15,17],"h1",{"id":16},"introducing-teleconvert-a-transcoding-pool-over-ssh","Introducing TeleConvert: A Transcoding Pool over SSH",[19,20,21],"p",{},"Video conversion is easy to start and painfully slow to finish. A laptop can spend an entire weekend working through a media directory while faster desktops, servers, and old workstations sit idle nearby. TeleConvert turns those machines into a shared transcoding pool without asking you to deploy a worker service on any of them.",[19,23,24,25,29,30,33,34,37],{},"TeleConvert is a small Go command-line application that discovers media files, distributes jobs across local and remote workers, and displays the whole queue in a live terminal dashboard. A worker only needs SSH access and an encoder such as ",[26,27,28],"code",{},"ffmpeg"," or ",[26,31,32],{},"HandBrakeCLI"," on its ",[26,35,36],{},"PATH",". There is no agent, daemon, container, database server, or web control plane to maintain.",[19,39,40],{},"That makes TeleConvert useful for a home lab, a temporary group of cloud machines, or any collection of Linux and macOS systems that can already communicate over SSH.",[42,43,45],"h2",{"id":44},"the-basic-idea","The basic idea",[19,47,48],{},"You run TeleConvert on the machine that holds your source media. A YAML file describes the available workers, how many jobs each worker may run, and the encoder command to execute. TeleConvert then manages the queue:",[50,51,57],"pre",{"className":52,"code":54,"language":55,"meta":56},[53],"language-text","Input files\n    │\n    ├─ local worker ───────────────→ encoded output\n    ├─ SSH worker 1 ── upload\u002Frun ─→ encoded output\n    └─ SSH worker 2 ── upload\u002Frun ─→ encoded output\n","text","",[26,58,54],{"__ignoreMap":56},[19,60,61,62,29,65,68],{},"Remote uploads are atomic and checksum-verified. Worker heartbeats and busy-slot detection keep the scheduler aware of available capacity, while interrupted jobs return to the pending queue instead of being recorded as complete. A clean ",[26,63,64],{},"Ctrl-C",[26,66,67],{},"SIGTERM"," shuts down active encoders and preserves recoverable state.",[19,70,71,72,75,76,79],{},"TeleConvert is also encoder-agnostic. Each node has a command template containing ",[26,73,74],{},"{{.Input}}"," and ",[26,77,78],{},"{{.Output}}","; those placeholders are replaced with the paths for each job. The template can call HandBrakeCLI, ffmpeg, or another command that follows the same input\u002Foutput model.",[42,81,83],{"id":82},"install-teleconvert","Install TeleConvert",[19,85,86],{},"Install the latest compiled release on Linux or macOS:",[50,88,92],{"className":89,"code":90,"language":91,"meta":56,"style":56},"language-bash shiki shiki-themes github-light github-dark","curl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002FAlchemist-Aloha\u002Fteleconvert\u002Fmain\u002Finstall.sh | bash\n","bash",[26,93,94],{"__ignoreMap":56},[95,96,99,103,107,111,115],"span",{"class":97,"line":98},"line",1,[95,100,102],{"class":101},"sScJk","curl",[95,104,106],{"class":105},"sj4cs"," -fsSL",[95,108,110],{"class":109},"sZZnC"," https:\u002F\u002Fraw.githubusercontent.com\u002FAlchemist-Aloha\u002Fteleconvert\u002Fmain\u002Finstall.sh",[95,112,114],{"class":113},"szBVR"," |",[95,116,117],{"class":101}," bash\n",[19,119,120,121,124,125,127,128,130],{},"The installer places the binary in ",[26,122,123],{},"~\u002F.local\u002Fbin"," and creates a default configuration when one does not already exist. Make sure ",[26,126,123],{}," is on your shell's ",[26,129,36],{},", then verify the installation:",[50,132,134],{"className":89,"code":133,"language":91,"meta":56,"style":56},"teleconvert -version\n",[26,135,136],{"__ignoreMap":56},[95,137,138,141],{"class":97,"line":98},[95,139,140],{"class":101},"teleconvert",[95,142,143],{"class":105}," -version\n",[19,145,146],{},"The install locations and release version can be overridden when needed:",[50,148,150],{"className":89,"code":149,"language":91,"meta":56,"style":56},"export TELECONVERT_INSTALL_DIR=\"$HOME\u002Fbin\"\nexport TELECONVERT_CONFIG_DIR=\"$HOME\u002F.config\u002Fteleconvert\"\nexport TELECONVERT_VERSION=v1.2.3\ncurl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002FAlchemist-Aloha\u002Fteleconvert\u002Fmain\u002Finstall.sh | bash\n",[26,151,152,173,190,203],{"__ignoreMap":56},[95,153,154,157,161,164,167,170],{"class":97,"line":98},[95,155,156],{"class":113},"export",[95,158,160],{"class":159},"sVt8B"," TELECONVERT_INSTALL_DIR",[95,162,163],{"class":113},"=",[95,165,166],{"class":109},"\"",[95,168,169],{"class":159},"$HOME",[95,171,172],{"class":109},"\u002Fbin\"\n",[95,174,176,178,181,183,185,187],{"class":97,"line":175},2,[95,177,156],{"class":113},[95,179,180],{"class":159}," TELECONVERT_CONFIG_DIR",[95,182,163],{"class":113},[95,184,166],{"class":109},[95,186,169],{"class":159},[95,188,189],{"class":109},"\u002F.config\u002Fteleconvert\"\n",[95,191,193,195,198,200],{"class":97,"line":192},3,[95,194,156],{"class":113},[95,196,197],{"class":159}," TELECONVERT_VERSION",[95,199,163],{"class":113},[95,201,202],{"class":159},"v1.2.3\n",[95,204,206,208,210,212,214],{"class":97,"line":205},4,[95,207,102],{"class":101},[95,209,106],{"class":105},[95,211,110],{"class":109},[95,213,114],{"class":113},[95,215,117],{"class":101},[19,217,218],{},"To build from source instead:",[50,220,222],{"className":89,"code":221,"language":91,"meta":56,"style":56},"git clone https:\u002F\u002Fgithub.com\u002FAlchemist-Aloha\u002Fteleconvert.git\ncd teleconvert\ngo mod tidy\ngo build -o teleconvert .\n",[26,223,224,235,243,254],{"__ignoreMap":56},[95,225,226,229,232],{"class":97,"line":98},[95,227,228],{"class":101},"git",[95,230,231],{"class":109}," clone",[95,233,234],{"class":109}," https:\u002F\u002Fgithub.com\u002FAlchemist-Aloha\u002Fteleconvert.git\n",[95,236,237,240],{"class":97,"line":175},[95,238,239],{"class":105},"cd",[95,241,242],{"class":109}," teleconvert\n",[95,244,245,248,251],{"class":97,"line":192},[95,246,247],{"class":101},"go",[95,249,250],{"class":109}," mod",[95,252,253],{"class":109}," tidy\n",[95,255,256,258,261,264,267],{"class":97,"line":205},[95,257,247],{"class":101},[95,259,260],{"class":109}," build",[95,262,263],{"class":105}," -o",[95,265,266],{"class":109}," teleconvert",[95,268,269],{"class":109}," .\n",[42,271,273],{"id":272},"prepare-the-workers","Prepare the workers",[19,275,276],{},"Every remote node needs:",[278,279,280,284,294,297],"ul",{},[281,282,283],"li",{},"SSH access from the controller machine",[281,285,286,288,289,291,292],{},[26,287,28],{},", ",[26,290,32],{},", or the command used by its template on ",[26,293,36],{},[281,295,296],{},"Enough temporary disk space for the active input and output files",[281,298,299],{},"Write access to its configured temporary directory",[19,301,302],{},"SSH keys are the simplest option for unattended queues. Test each connection before starting TeleConvert:",[50,304,306],{"className":89,"code":305,"language":91,"meta":56,"style":56},"ssh -i ~\u002F.ssh\u002Fid_rsa user@192.168.1.100\nHandBrakeCLI --version\n",[26,307,308,322],{"__ignoreMap":56},[95,309,310,313,316,319],{"class":97,"line":98},[95,311,312],{"class":101},"ssh",[95,314,315],{"class":105}," -i",[95,317,318],{"class":109}," ~\u002F.ssh\u002Fid_rsa",[95,320,321],{"class":109}," user@192.168.1.100\n",[95,323,324,326],{"class":97,"line":175},[95,325,32],{"class":101},[95,327,328],{"class":105}," --version\n",[19,330,331],{},"The encoder can be different on each node. This is useful when one machine has a hardware encoder, another is tuned for high-quality CPU encoding, and the local system should handle only one lightweight job at a time.",[42,333,335],{"id":334},"configure-the-worker-pool","Configure the worker pool",[19,337,338],{},"The default configuration path is:",[50,340,343],{"className":341,"code":342,"language":55,"meta":56},[53],"~\u002F.config\u002Fteleconvert\u002Fteleconvert.yaml\n",[26,344,342],{"__ignoreMap":56},[19,346,347],{},"The following example defines one remote worker and one local worker:",[50,349,353],{"className":350,"code":351,"language":352,"meta":56,"style":56},"language-yaml shiki shiki-themes github-light github-dark","nodes:\n\n- name: \"remote\"\n  address: \"192.168.1.100:22\"\n  user: \"user\"\n  ssh_key: \"\u002Fhome\u002Fuser\u002F.ssh\u002Fid_rsa\"\n  max_concurrent: 1\n  command: \"HandBrakeCLI -i {{.Input}} -o {{.Output}} -e x265 -q 27.0 -a 1 -E fdk_aac -B 160 -6 stereo -f mkv --deinterlace -w 1920 -l 1080 -O\"\n  tmp_dir: \"\u002Ftmp\u002Fteleconvert\"\n\n- name: \"local-encoder\"\n  address: \"localhost\"\n  max_concurrent: 1\n  command: \"HandBrakeCLI -i {{.Input}} -o {{.Output}} -e x265 -q 27.0 -a 1 -E fdk_aac -B 160 -6 stereo -f mkv --deinterlace -w 1920 -l 1080 -O\"\n  tmp_dir: \"\u002Ftmp\u002Fteleconvert\"\n","yaml",[26,354,355,364,370,384,394,405,416,427,438,449,454,466,476,485,494],{"__ignoreMap":56},[95,356,357,361],{"class":97,"line":98},[95,358,360],{"class":359},"s9eBZ","nodes",[95,362,363],{"class":159},":\n",[95,365,366],{"class":97,"line":175},[95,367,369],{"emptyLinePlaceholder":368},true,"\n",[95,371,372,375,378,381],{"class":97,"line":192},[95,373,374],{"class":159},"- ",[95,376,377],{"class":359},"name",[95,379,380],{"class":159},": ",[95,382,383],{"class":109},"\"remote\"\n",[95,385,386,389,391],{"class":97,"line":205},[95,387,388],{"class":359},"  address",[95,390,380],{"class":159},[95,392,393],{"class":109},"\"192.168.1.100:22\"\n",[95,395,397,400,402],{"class":97,"line":396},5,[95,398,399],{"class":359},"  user",[95,401,380],{"class":159},[95,403,404],{"class":109},"\"user\"\n",[95,406,408,411,413],{"class":97,"line":407},6,[95,409,410],{"class":359},"  ssh_key",[95,412,380],{"class":159},[95,414,415],{"class":109},"\"\u002Fhome\u002Fuser\u002F.ssh\u002Fid_rsa\"\n",[95,417,419,422,424],{"class":97,"line":418},7,[95,420,421],{"class":359},"  max_concurrent",[95,423,380],{"class":159},[95,425,426],{"class":105},"1\n",[95,428,430,433,435],{"class":97,"line":429},8,[95,431,432],{"class":359},"  command",[95,434,380],{"class":159},[95,436,437],{"class":109},"\"HandBrakeCLI -i {{.Input}} -o {{.Output}} -e x265 -q 27.0 -a 1 -E fdk_aac -B 160 -6 stereo -f mkv --deinterlace -w 1920 -l 1080 -O\"\n",[95,439,441,444,446],{"class":97,"line":440},9,[95,442,443],{"class":359},"  tmp_dir",[95,445,380],{"class":159},[95,447,448],{"class":109},"\"\u002Ftmp\u002Fteleconvert\"\n",[95,450,452],{"class":97,"line":451},10,[95,453,369],{"emptyLinePlaceholder":368},[95,455,457,459,461,463],{"class":97,"line":456},11,[95,458,374],{"class":159},[95,460,377],{"class":359},[95,462,380],{"class":159},[95,464,465],{"class":109},"\"local-encoder\"\n",[95,467,469,471,473],{"class":97,"line":468},12,[95,470,388],{"class":359},[95,472,380],{"class":159},[95,474,475],{"class":109},"\"localhost\"\n",[95,477,479,481,483],{"class":97,"line":478},13,[95,480,421],{"class":359},[95,482,380],{"class":159},[95,484,426],{"class":105},[95,486,488,490,492],{"class":97,"line":487},14,[95,489,432],{"class":359},[95,491,380],{"class":159},[95,493,437],{"class":109},[95,495,497,499,501],{"class":97,"line":496},15,[95,498,443],{"class":359},[95,500,380],{"class":159},[95,502,448],{"class":109},[19,504,505,506,509,510,75,512,514],{},"Every ",[26,507,508],{},"command"," must contain both ",[26,511,74],{},[26,513,78],{},". TeleConvert validates the template and substitutes the correct paths for each job.",[19,516,517,520,521,524],{},[26,518,519],{},"max_concurrent"," controls the number of encoder processes assigned to that node. Start with ",[26,522,523],{},"1",". Increase it only after checking CPU, GPU, memory, storage throughput, and encoder behavior under simultaneous jobs. A machine that completes one transcode quickly may become slower overall when too many encoders compete for the same hardware.",[42,526,528],{"id":527},"run-a-conversion-queue","Run a conversion queue",[19,530,531],{},"Point TeleConvert at one file or an entire directory:",[50,533,535],{"className":89,"code":534,"language":91,"meta":56,"style":56},"teleconvert \\\n  -input \u002Fpath\u002Fto\u002Fvideos \\\n  -output-dir \u002Fpath\u002Fto\u002Foutput \\\n  -output-ext .mp4 \\\n  -config ~\u002F.config\u002Fteleconvert\u002Fteleconvert.yaml\n",[26,536,537,544,554,564,574],{"__ignoreMap":56},[95,538,539,541],{"class":97,"line":98},[95,540,140],{"class":101},[95,542,543],{"class":105}," \\\n",[95,545,546,549,552],{"class":97,"line":175},[95,547,548],{"class":105},"  -input",[95,550,551],{"class":109}," \u002Fpath\u002Fto\u002Fvideos",[95,553,543],{"class":105},[95,555,556,559,562],{"class":97,"line":192},[95,557,558],{"class":105},"  -output-dir",[95,560,561],{"class":109}," \u002Fpath\u002Fto\u002Foutput",[95,563,543],{"class":105},[95,565,566,569,572],{"class":97,"line":205},[95,567,568],{"class":105},"  -output-ext",[95,570,571],{"class":109}," .mp4",[95,573,543],{"class":105},[95,575,576,579],{"class":97,"line":396},[95,577,578],{"class":105},"  -config",[95,580,581],{"class":109}," ~\u002F.config\u002Fteleconvert\u002Fteleconvert.yaml\n",[19,583,584,585,588,589,592,593,596],{},"If ",[26,586,587],{},"-output-dir"," is omitted, TeleConvert creates a ",[26,590,591],{},"converted"," directory beside each source file. The default output extension is ",[26,594,595],{},".mp4",".",[19,598,599],{},"Available flags include:",[601,602,603,616],"table",{},[604,605,606],"thead",{},[607,608,609,613],"tr",{},[610,611,612],"th",{},"Flag",[610,614,615],{},"Purpose",[617,618,619,630,640,649,661,671,681,694,707],"tbody",{},[607,620,621,627],{},[622,623,624],"td",{},[26,625,626],{},"-config",[622,628,629],{},"Select a YAML configuration file",[607,631,632,637],{},[622,633,634],{},[26,635,636],{},"-input",[622,638,639],{},"Choose the required input file or directory",[607,641,642,646],{},[622,643,644],{},[26,645,587],{},[622,647,648],{},"Choose one destination directory",[607,650,651,656],{},[622,652,653],{},[26,654,655],{},"-output-ext",[622,657,658,659],{},"Set the output extension; default ",[26,660,595],{},[607,662,663,668],{},[622,664,665],{},[26,666,667],{},"-delete-source",[622,669,670],{},"Delete each source only after its job succeeds",[607,672,673,678],{},[622,674,675],{},[26,676,677],{},"-continue-on-error",[622,679,680],{},"Continue after individual failures; enabled by default",[607,682,683,691],{},[622,684,685,29,688],{},[26,686,687],{},"-verbose",[26,689,690],{},"-v",[622,692,693],{},"Show verbose lifecycle logging",[607,695,696,701],{},[622,697,698],{},[26,699,700],{},"-poll-interval",[622,702,703,704],{},"Set the worker monitor interval; default ",[26,705,706],{},"2s",[607,708,709,714],{},[622,710,711],{},[26,712,713],{},"-version",[622,715,716],{},"Print the embedded build version and exit",[19,718,719,720,722],{},"Treat ",[26,721,667],{}," as an explicit cleanup mode, not a routine default. Run a normal queue first and inspect its outputs before allowing any automated source deletion.",[42,724,726],{"id":725},"follow-progress-in-the-terminal-dashboard","Follow progress in the terminal dashboard",[19,728,729],{},"In an interactive terminal, TeleConvert opens a full-screen dashboard. The top bar shows total completion and failure counts. The worker panel lists every slot, its current state, progress, elapsed time, and input file. Two log panes separate TeleConvert lifecycle events from the raw output of the selected encoder.",[50,731,734],{"className":732,"code":733,"language":55,"meta":56},[53],"┌─ TELECONVERT  [=========         ]  7\u002F15 done  0 failed ───────────────┐\n┌─ Workers ──────────────────────────────────────────────────────────────┐\n│ > remote         encoding   [==============]  42.3%  01:23  video1.mkv│\n│   local-encoder  encoding   [=============== ] 78.5%  02:07  video4.mkv│\n└────────────────────────────────────────────────────────────────────────┘\n┌─ TeleConvert output ───────────────────────────────────────────────────┐\n│ 14:23:01  remote:video1.mkv encoding started                           │\n└────────────────────────────────────────────────────────────────────────┘\n┌─ Encoder output — remote [live] ───────────────────────────────────────┐\n│ Encoding: task 1 of 1, 42.37 % (12.00 fps)                             │\n└────────────────────────────────────────────────────────────────────────┘\n",[26,735,733],{"__ignoreMap":56},[19,737,738],{},"Dashboard controls:",[278,740,741,761,770,785,794,803],{},[281,742,743,746,747,288,750,746,753,756,757,760],{},[26,744,745],{},"↑"," \u002F ",[26,748,749],{},"↓",[26,751,752],{},"j",[26,754,755],{},"k",", or ",[26,758,759],{},"Tab"," selects a worker slot",[281,762,763,765,766,769],{},[26,764,523],{},"–",[26,767,768],{},"9"," selects a worker directly",[281,771,772,746,775,29,778,746,781,784],{},[26,773,774],{},"Page Up",[26,776,777],{},"Page Down",[26,779,780],{},"u",[26,782,783],{},"d"," scrolls encoder output",[281,786,787,746,790,793],{},[26,788,789],{},"g",[26,791,792],{},"Home"," jumps to the oldest retained output",[281,795,796,746,799,802],{},[26,797,798],{},"G",[26,800,801],{},"End"," returns to live output",[281,804,805,29,808,810],{},[26,806,807],{},"q",[26,809,64],{}," stops active encoders cleanly and exits",[19,812,813,814,29,816,818],{},"After a successful interactive run, the dashboard stays open so you can review the final logs. Press ",[26,815,807],{},[26,817,64],{}," when finished. Redirected and other non-interactive runs remain line-oriented and exit automatically after the queue completes.",[42,820,822],{"id":821},"a-practical-first-run","A practical first run",[19,824,825],{},"Before handing TeleConvert a large archive:",[827,828,829,832,835,841,846,849],"ol",{},[281,830,831],{},"Confirm that SSH key authentication works for every remote node.",[281,833,834],{},"Run the configured encoder command manually on a small sample file.",[281,836,837,838,596],{},"Start each node with ",[26,839,840],{},"max_concurrent: 1",[281,842,843,844,596],{},"Process a copied test directory without ",[26,845,667],{},[281,847,848],{},"Inspect playback, audio, subtitles, resolution, and output size.",[281,850,851],{},"Increase concurrency one node at a time while watching system load.",[19,853,854],{},"This short test verifies more than connectivity. It confirms that the exact encoder options make sense for your media before the same template is applied across the full queue.",[42,856,858],{"id":857},"troubleshooting","Troubleshooting",[278,860,861,871,879,890,899,908,917],{},[281,862,863,867,868,870],{},[864,865,866],"strong",{},"The remote node never starts:"," Test the configured address, user, and SSH key with the regular ",[26,869,312],{}," command.",[281,872,873,876,877,596],{},[864,874,875],{},"Encoder command not found:"," Install the encoder on that worker and make sure it is available on the non-interactive SSH ",[26,878,36],{},[281,880,881,884,885,75,887,889],{},[864,882,883],{},"Configuration is rejected:"," Check that every node command includes both ",[26,886,74],{},[26,888,78],{}," exactly.",[281,891,892,895,896,596],{},[864,893,894],{},"Remote job cannot create files:"," Check free space and permissions for the node's ",[26,897,898],{},"tmp_dir",[281,900,901,904,905,907],{},[864,902,903],{},"One file fails repeatedly:"," Run again with ",[26,906,687],{},", select that worker in the dashboard, and inspect its raw encoder output.",[281,909,910,913,914,916],{},[864,911,912],{},"A worker is overloaded:"," Reduce its ",[26,915,519],{}," value before changing global behavior.",[281,918,919,922,923,29,925,927],{},[864,920,921],{},"You need to stop the queue:"," Use ",[26,924,807],{},[26,926,64],{},". TeleConvert stops active encoder processes cleanly and returns interrupted work to a recoverable pending state.",[42,929,931],{"id":930},"use-the-machines-you-already-have","Use the machines you already have",[19,933,934],{},"TeleConvert does not attempt to be a general cluster scheduler. It solves the narrower problem of assigning file conversions to machines that are already reachable over SSH. The controller owns the queue, each worker runs a familiar encoder command, and the dashboard keeps the entire operation visible.",[19,936,937],{},"That small operating model is the main advantage: add a machine with a few YAML lines, remove it just as easily, and use otherwise idle hardware without deploying another permanent service.",[19,939,940,941,948],{},"Visit the ",[942,943,947],"a",{"href":944,"rel":945},"https:\u002F\u002Fgithub.com\u002FAlchemist-Aloha\u002Fteleconvert",[946],"nofollow","TeleConvert repository"," for current releases, source code, and configuration examples.",[950,951,952],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":56,"searchDepth":175,"depth":175,"links":954},[955,956,957,958,959,960,961,962,963],{"id":44,"depth":175,"text":45},{"id":82,"depth":175,"text":83},{"id":272,"depth":175,"text":273},{"id":334,"depth":175,"text":335},{"id":527,"depth":175,"text":528},{"id":725,"depth":175,"text":726},{"id":821,"depth":175,"text":822},{"id":857,"depth":175,"text":858},{"id":930,"depth":175,"text":931},"\u002Farticles\u002Fmedia-toolkit-cover.webp","2026-08-09T00:00:00.000Z","Turn idle Linux and macOS machines into a parallel video-transcoding pool using SSH, ffmpeg or HandBrakeCLI, and one YAML file.","md",{"title":969},{"Introducing TeleConvert":970},"A Transcoding Pool over SSH","page",{},"\u002Farticles\u002Fintroducing-teleconvert",{"title":5,"description":966},"articles\u002F9.introducing-teleconvert","sjk0ADgcER4cX7s14seRwA5MRviliAMG-W39KrQvWZk",1786980373685]