{"id":17661626,"url":"https://github.com/djthorpe/remotes","last_synced_at":"2025-05-07T18:21:22.667Z","repository":{"id":144227492,"uuid":"115913064","full_name":"djthorpe/remotes","owner":"djthorpe","description":"Transcoding, Sending and Receiving Infrared Remote codes","archived":false,"fork":false,"pushed_at":"2019-06-11T07:38:27.000Z","size":547,"stargazers_count":6,"open_issues_count":5,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-31T12:57:21.937Z","etag":null,"topics":["internet-of-things","iot","ir","lirc","raspberry-pi","remote-control"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djthorpe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-01T10:41:26.000Z","updated_at":"2022-08-28T20:27:41.000Z","dependencies_parsed_at":"2023-04-09T21:46:15.798Z","dependency_job_id":null,"html_url":"https://github.com/djthorpe/remotes","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djthorpe%2Fremotes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djthorpe%2Fremotes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djthorpe%2Fremotes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djthorpe%2Fremotes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djthorpe","download_url":"https://codeload.github.com/djthorpe/remotes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252931817,"owners_count":21827172,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["internet-of-things","iot","ir","lirc","raspberry-pi","remote-control"],"created_at":"2024-10-23T17:22:40.503Z","updated_at":"2025-05-07T18:21:22.643Z","avatar_url":"https://github.com/djthorpe.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IR Sending and Receiving\n\nThis repository contains software which provides the ability to send \nand receive infrared signals for a variety of devices usually controlled\nusing Infrared Remote Controllers (TV's, CD players, etc)\non a Raspberry Pi. In order to use it, you'll need some IR Sending and \nReceiving hardware, which you can build yourself (more details below) or\npurchase.\n\nThe types of remote controls supported may have one of the following encoding\nschemes:\n\n  * Sony 12- 15- and 20- bit (CODEC_SONY12,CODEC_SONY15,CODEC_SONY20)\n  * Panasonic (CODEC_PANASONIC)\n  * NEC 32- and 16- bit (CODEC_NEC32, CODEC_NEC16 and CODEC_APPLETV)\n  * Philips RC5 (CODEC_RC5) __In development__\n\nIt's fairly easy to add other encoding schemes, please see the Appendix below.\nThere is some software available to interact with your remotes:\n\n  * `ir_learn` can be used to learn a new remote or update an existing remote\n    in the database of \"key mappings\"\n  * `ir_rcv` can be used for debugging remotes\n  * `ir_send` can be used for sending commands\n\nIn addition there are a couple of microservice binaries which allow remote\nservices and clients to interact remotely through [gRPC](https://grpc.io/):\n\n  * `remotes-service` is a microservice allowing remotes to be interacted with\n    remotely through the gRPC protocol\n  * `remotes-client` is an example command-line client which can interact with\n    the microservice through the gRPC protocol\n\nUltimately the mircoservice should form a larger service for home automation or \ncould be used to develop a web-accessible application; this is being developed elsewhere.\n\n## License\n\nPlease see the [LICENSE](https://github.com/djthorpe/remotes/blob/master/LICENSE)\nfile for how to redistribute in source or binary form. Ultimately you should\ncredit the authors on redistribution as per paragraph four of that license.\n\n## Feedback\n\nAll feedback gratefully received, either as bugs, features or questions. For the\nformer, please use the GitHub issue tracker. For the latter, send me an email\nwhich is listed in the GitHub [repository](https://github.com/djthorpe/remotes).\n\n# Installation\n\n## Hardware Installation\n\nYou'll need an IR sender and/or receiver plugged into your GPIO port. There\nis a schematic and bill of materials below, plus a link to manufacture\na PCB, if you want to make one up, or you can easily purchase one or breadboard\nit.\n\nThe hardware has been tested on a modern Raspbian installation but ultimately \nany Linux which is compiled with the `lirc` module should work fine. For a \nRaspberry Pi, you should add this to your `/boot/config.txt` file modifying\nthe GPIO pins in order to load the LIRC (Linux Infrared Control) driver, \nand then reboot your Raspberry Pi:\n\n```\ndtoverlay=lirc-rpi,gpio_in_pin=22,gpio_out_pin=23\n```\n\nYour LIRC should then be able to see the device `/dev/lirc0`. If not check output \nof the `lsmod` command.  The best reference for how to interact with the device at the low \nlevel is [here](https://www.kernel.org/doc/html/latest/media/uapi/rc/lirc-dev-intro.html).\n\n## Software Installation\n\nYou'll need a working Go Language environment to compile and install the software:\n\n```\nbash% go get github.com/djthorpe/remotes\nbash% cd ${GOPATH}/src/github.com/djthorpe/remotes\nbash% cmd/build-tool.sh # To install the command-line utilities\n```\n\nThis will result in a number of binaries installed in `${GOBIN}`: `ir_learn`, \n`ir_rcv` and `ir_send` which are described below. For microservices installation\non Raspberry Pi you can download and install Protocol Buffers, gRPC and then \ninstall the binaries:\n\n```\nbash% sudo apt install protobuf-compiler\nbash% sudo apt install libprotobuf-dev\nbash% go get -u github.com/golang/protobuf/protoc-gen-go\nbash% cd ${GOPATH}/src/github.com/djthorpe/remotes\nbash% cmd/build-rpc.sh # To install the RPC binaries\n```\n\nOn a Macintosh with MacPorts try the following:\n\n```\nbash% brew install protobuf\nbash% go get -u github.com/golang/protobuf/protoc-gen-go\nbash% cd ${GOPATH}/src/github.com/djthorpe/remotes\nbash% cmd/build-rpc.sh # To install the RPC binaries\n```\n\nThis will result in the installation of the service `remotes-service`and and example\ncommand-line client `remotes-client`. More information on these binaries below.\n\n# Usage\n\n## Running Command-Line Tools\n\nBefore you use the command-line tools, you will need to create a folder at\n`/var/local/remotes` which will be used for storing the key mapping \ndatabase files for the remotes, which is stored in XML format with the file\nextension `.keymap`. The command-line tools are invoked as follows:\n\n```\n  ir_rcv \u003ccommon flags\u003e\n  ir_learn \u003ccommon flags\u003e -device \u003cdevice_name\u003e -repeats \u003cn\u003e -multicodec \u003ckey_list\u003e\n  ir_send \u003ccommon flags\u003e -device \u003cdevice_name\u003e -repeats \u003cn\u003e \u003ckey_list\u003e  \n```\n\nYou can use the following optional common flags with all the binaries:\n\n```\n  -debug\n    \tSet debugging mode\n  -verbose\n    \tVerbose logging\n  -log.append\n    \tWhen writing log to file, append output to end of file\n  -log.file string\n    \tFile for logging (default: log to stderr)\n  -lirc.device string\n      \tLIRC device (default \"/dev/lirc0\")\n  -keymap.db string\n    \tKey mapping database path (default \"/var/local/remotes\")\n  -keymap.ext string\n    \tKey mapping file extension  (default \".keymap\")         \n```\n\nHere is a detailed description of how to use each tool. You can check to see if the\nsoftware is working with the following command:\n\n```\nbash% ir_rcv\n```\n\nThis will display a table of learnt keys and also display scan codes which have yet to be \nmatched (marked as `\u003cunmapped\u003e`.) This is what some example output might look like:\n\n```\nName                 Key                       Scancode   Device     Codec           Event                  Timestamp\n-------------------- ------------------------- ---------- ---------- --------------- ---------------------- ----------\nMenu                 KEYCODE_MENU              0x00000040 0x0000009F CODEC_APPLETV   INPUT_EVENT_KEYPRESS   2.117s\nEject                KEYCODE_EJECT             0x0000808D 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYPRESS   11.643s\nEject                KEYCODE_EJECT             0x0000808D 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYREPEAT  11.773s\nPad 3                KEYCODE_KEYPAD_3          0x00004845 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYPRESS   12.425s\nPad 3                KEYCODE_KEYPAD_3          0x00004845 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYREPEAT  12.555s\nNav Right            KEYCODE_NAV_RIGHT         0x0000111C 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYPRESS   13.925s\nNav Right            KEYCODE_NAV_RIGHT         0x0000111C 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYREPEAT  14.056s\n\u003cunmapped\u003e           \u003cunmapped\u003e                0x0000CCC1 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYPRESS   14.97s\n\u003cunmapped\u003e           \u003cunmapped\u003e                0x0000CCC1 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYREPEAT  15.102s\n\u003cunmapped\u003e           \u003cunmapped\u003e                0x0000CCC1 0x40040D00 CODEC_PANASONIC INPUT_EVENT_KEYREPEAT  15.929s\nPad 2                KEYCODE_KEYPAD_2          0x00000008 0x00000076 CODEC_NEC32     INPUT_EVENT_KEYPRESS   18.98s\nPad 2                KEYCODE_KEYPAD_2          0x00000008 0x00000076 CODEC_NEC32     INPUT_EVENT_KEYPRESS   19.231s\nPause                KEYCODE_PAUSE             0x00000020 0x00000076 CODEC_NEC32     INPUT_EVENT_KEYPRESS   21.628s\n\u003cunmapped\u003e           \u003cunmapped\u003e                0x000000C0 0x00000076 CODEC_NEC32     INPUT_EVENT_KEYPRESS   22.52s\n```\n\nOnce you've finished using `ir_rcv` press CTRL+C to quit the software.\n\nTo learn a new or existing remote, use the `ir_learn` command-line tool as follows:\n\n```\n  bash% ir_learn -device \"DVD Player\"\n```\n\nThis will cycle through all keys and will prompt you to press a key on your remote to map it.\nIf you don't press the key within a few seconds, no mapping is created and the next key is\nlearnt. Press the CTRL+C combination in order to abort the learning without saving.\n\nYou can learn specific keys by including keys as arguments. For example, to learn the keypad digits\nand the navigation buttons use:\n\n```\n  bash% ir_learn -device \"DVD Player\" keypad,nav,play,pause,stop\n```\n\nYou can re-invoke the tool with the same device name to modify existing key mappings. Once the\nremote device has been learnt, you can use the `ir_send` utility to check the keymapping database \nand send codes to your device:\n\n```\nbash% ir_send\nNAME                 CODEC                DEVICE     KEYS    REPEATS\n-------------------- -------------------- ---------- ------- -------\nappletv              CODEC_APPLETV        0x0000009F       6       0\nKR21                 CODEC_NEC32          0x000000FF      39       0\nSqueezebox           CODEC_NEC32          0x00007689      31       0\nRotel                CODEC_NEC32          0x0000C188      15       3\nPanasonic DVD        CODEC_PANASONIC      0x00000D00      32       0\nSony TV              CODEC_SONY12         0x00000010      28       3\nSony VCR             CODEC_SONY12         0x0000001A      26       3\n\n\nbash% ir_send -device dvd\nKEY                  CODE                      CODEC             DEVICE     SCANCODE   REPEATS\n-------------------- ------------------------- ----------------- ---------- ---------- -------\nNav Back             KEYCODE_NAV_BACK          CODEC_PANASONIC   0x40040D00 0x0000818C       0\nNav Down             KEYCODE_NAV_DOWN          CODEC_PANASONIC   0x40040D00 0x0000616C       0\nNav Left             KEYCODE_NAV_LEFT          CODEC_PANASONIC   0x40040D00 0x0000E1EC       0\nPad 0                KEYCODE_KEYPAD_0          CODEC_PANASONIC   0x40040D00 0x00009895       0\nPad 2                KEYCODE_KEYPAD_2          CODEC_PANASONIC   0x40040D00 0x00008885       0\nPad 7                KEYCODE_KEYPAD_7          CODEC_PANASONIC   0x40040D00 0x00006865       0\nSearch Left          KEYCODE_SEARCH_LEFT       CODEC_PANASONIC   0x40040D00 0x0000202D       0\nPower Toggle         KEYCODE_POWER_TOGGLE      CODEC_PANASONIC   0x40040D00 0x0000BCB1       0\nSleep                KEYCODE_SLEEP             CODEC_PANASONIC   0x40040D00 0x0000D7DA       0\n```\n\nIf you invoke `ir_send` without any arguments, it will display a list of learnt devices. If you invoke\nit with a `-device` flag it should display a list of learnt keys. If you also include a `-repeats`\nflag with a value, it will modify the default number of times a code is transmitted. For example:\n\n```\nbash% ir_send -device appletv -repeats 3\nNAME                 CODEC                DEVICE     KEYS    REPEATS\n-------------------- -------------------- ---------- ------- -------\nappletv              CODEC_APPLETV        0x0000009F       6       3\n```\n\nFinally and most importantly, you can invoke it with one or more arguments to send an IR command. \nIf you have some ambigious key names, then you'll need to modify what you use on the command line \nto specify a key more exactly. For example,\n\n```\nbash% ir_send -device \"appletv\" volume\nAmbiguous key: volume (It could mean one of 'Volume Down','Volume Up')\n\nbash% ir_send -device \"appletv\" volume_down\nKEY                  CODE                      CODEC             DEVICE     SCANCODE   REPEATS\n-------------------- ------------------------- ----------------- ---------- ---------- -------\nVolume Down          KEYCODE_VOLUME_DOWN       CODEC_APPLETV     0x0000009F 0x000000B0       3\n```\n\nThere are some cases where a single remote outputs different types of encoding. For example,\nI have a Sony TV remote which does this. In order to learn both sets of encodings for a single\n\"device\" use the `-multicodec` flag when learning the new encoded commands, or just switch it\non before learning new commands.\n\nIf you have any problems with the database, you can clean up the individual files which are simple\nXML files usually stored under `/var/local/remotes` unless you've changed the path.\n\n## Running Microservices\n\nThe \"microservice\" has been developed with a view to integrating the IR sending and receiving into\na wider home automation environment. The service binary is called `remotes-service` and there is\nan example client which communicates with the server called `remotes-client`. I recommend you\ngenerate an SSL certificate and key you place in the `/var/local/remotes` folder, if you have\nOpenSSL installed:\n\n```\nbash% DAYS=99999\nbash% OUT=/var/local/remotes\nbash% ORG=\"mutablelogic\"\nbash% HOST=`hostname`\nbash% openssl req \\\n  -x509 -nodes \\\n  -newkey rsa:2048 \\\n  -keyout \"${OUT}/selfsigned.key\" \\\n  -out \"${OUT}/selfsigned.crt\" \\\n  -days \"${DAYS}\" \\\n  -subj \"/C=GB/L=London/O=${ORG}/CN=${HOST}\"\n```\n\nAssuming you can a working LIRC module, you can invoke the service in the background \nas follows:\n\n```\nbash% remotes-service \\\n  -rpc.sslkey /var/local/remotes/selfsigned.key \\\n  -rpc.sslcert /var/local/remotes/selfsigned.crt \\\n  -log.append -log.file=/var/local/remotes/remotes-service.log \\\n  -verbose \u0026\n```\n\nIt will use any random unused port or you can use the `-rpc.port` flag to set a specific port.\nIt also registers using mDNS under the service type `_remotes._tcp`. The [Protocol Buffer definition](https://github.com/djthorpe/remotes/blob/master/rpc/protobuf/remotes/remotes.proto)\nfor the service is called `remotes.Remotes` and has the following read-only methods:\n\n```\nservice Remotes {\n    // Return array of codecs supported\n    rpc Codecs (EmptyRequest) returns (CodecsReply);\n\n\t// Return array of keymaps\n\trpc KeyMaps (EmptyRequest) returns (KeyMapsReply);\n\n\t// Return keys learnt by keymap name, or all keys if an \n\t// empty request\n\trpc Keys (KeysRequest) returns (KeysReply);\n\n\t// Return all possible keys with one or more search terms\n\trpc LookupKeys (LookupKeysRequest) returns (KeysReply);\n\n    // Receive remote events\n    rpc Receive (EmptyRequest) returns (stream ReceiveReply);\n\n\t// Send a remote scancode\n\trpc SendScancode (SendScancodeRequest) returns (EmptyReply);\n\t\n\t// Send a remote keycode\n\trpc SendKeycode (SendKeycodeRequest) returns (EmptyReply);\n}\n```\n\nPossibly in a future version it might be worth adding write-methods as well\nbut you can use the command-line tools for the moment to learn new kep mappings.\n\n## Using the client\n\nThe `remotes-client` binary is an example client to communicate with the server,\nbut in reality of course you would develop your own client. Here are a couple\nof ways to invoke the example client:\n\n  * Use `remotes-client` with no arguments to print out a list of codecs and\n    keymaps supported, and stream events generated by key presses.\n  * Use `remotes-client -keymap \u003cname\u003e` to display a list of learnt keys\n  * Use `remotes-client -keymap \u003cname\u003e -send \u003ckey\u003e \u003ckey\u003e` to lookup keys\n    and transmit the pulses\n\nThere are a variety of other flags you can use when invoking `remotes-client`:\n\n```\nbash% remotes-client -help\nUsage of remotes-client:\n  -keymap string\n    \tKeymap\n  -send\n    \tSend keycode\n  -repeats uint\n    \tOverride repeats value\n  -addr string\n    \tGateway address\n  -mdns.domain string\n    \tDomain (default \"local.\")\n  -rpc.insecure\n    \tDisable SSL Connection\n  -rpc.service string\n    \tComma-separated list of service names\n  -rpc.skipverify\n    \tSkip SSL Verification (default true)\n  -rpc.timeout duration\n    \tConnection timeout\n  -verbose\n    \tVerbose logging\n  -debug\n    \tSet debugging mode\n  -log.append\n    \tWhen writing log to file, append output to end of file\n  -log.file string\n    \tFile for logging (default: log to stderr)\n```\n\nThe client uses mDNS to discover the microservice. Set the `rpc.timeout` parameter if\nthe microservice isn't being discovered in the time allotted for discovery. Set the \n`addr` parameter to choose a specific microservice or port:\n\n  * `-addr 192.168.86.35:33841` connects by IP address and port\n  * `-addr 192.168.86.35` connects to any discovered microservice with a specific IP address\n  * `-addr :33841` connects to any discovered microservice with a specific port\n\n# Appendix \n\n## Schematic\n\nHere is the schematic of the circuit with the bill of materials:\n\n![IR Schematic](https://raw.githubusercontent.com/djthorpe/remotes/master/etc/ir_schematic.png)\n\n\nIf you want to make a PCB of this design you can [manufacturer one here from Aisler](https://aisler.net/djthorpe/djthorpe/raspberry-pi-ir-sender-receiver). Total cost\nincluding components would cost about £5 / €5 / $5 per unit. Here's a picture of what the populated PCB looks like:\n\n![PCB](https://raw.githubusercontent.com/djthorpe/remotes/master/etc/aisler-pcb-201802.jpg)\n\nThis is the bill of materials:\n\n| Name | Part                  | Description |\n| ---- | ---- | ---- |\n| D1   |  Vishay TSAL6200      | 940nm IR LED, 5mm (T-1 3/4) Through Hole package |\n| D2   |  Vishay TSOP38238     | 38kHz IR Receiver, 950nm, 45m Range, Through Hole, 5 x 4.8 x 6.95mm |\n| Q1   |  Fairchild KSP2222ABU | NPN Transistor, 600 mA, 40 V, 3-Pin TO-92 |\n| R1   |  680Ω ±5% 0.25W       | Carbon Resistor, 0.25W, 5%, 680R |\n| R2   |  10K  ±5% 0.25W       | Carbon Resistor, 0.25W, 5%, 10K |\n| R3   |  36Ω ±1% 0.6W         | Carbon Resistor, 0.6W, 1%, 36R |\n| J1   |  26 Way PCB Header    | 2.54mm Pitch 13x2 Rows Straight PCB Socket |\n\n## Adding in more codecs\n\nYou can add in any number of Codecs which respond to LIRC pulse/space messages.\nIn order to do so, I would firstly understand how to develop a 'module' for the \n`gopi` framework. When registering the module in your `init` function, use\nmodule type `gopi.MODULE_TYPE_OTHER` and the module should have the name \nprefix `remotes/`. You will want a dependency on the `lirc` module. Here is what\na typical `init()` function may contain:\n\n```\n\tgopi.RegisterModule(gopi.Module{\n\t\tName:     \"remotes/panasonic\",\n\t\tRequires: []string{\"lirc\"},\n\t\tType:     gopi.MODULE_TYPE_OTHER,\n\t\tNew: func(app *gopi.AppInstance) (gopi.Driver, error) {\n\t\t\treturn gopi.Open(Codec{\n\t\t\t\tLIRC: app.ModuleInstance(\"lirc\").(gopi.LIRC),\n\t\t\t}, app.Logger)\n\t\t},\n\t}) \n```\n\nSecondly, your module should subscribe to events from the LIRC module\ninstance, and process them in the background. You'll receive a stream\nof LIRC events:\n\n```\ntype LIRCEvent interface {\n\tEvent\n\n\t// The type of message\n\tType() LIRCType\n\n\t// The value\n\tValue() uint32\n}\n```\n\nThe LIRC type will be one of `LIRC_TYPE_SPACE`,`LIRC_TYPE_PULSE`,\n`LIRC_TYPE_FREQUENCY`or `LIRC_TYPE_TIMEOUT`. Practically the Raspberry\nPi module only supports pulses and spaces and the value is measured\nin nanoseconds. For receiving and recognizing commands, it's perhaps\neasiest to develop a state machine which responds to and recognizes\ncommands, or resets back to the initial state if not recognized. Your\ncodec should then emit a `RemoteEvent` structure on recognition:\n\n```\ntype RemoteEvent struct {\n\tsource   Codec           // Codec that emitted the event\n\tts       time.Duration   // Rolling timecode\n\tdevice   uint32          // Unique device identifier, or 0\n\tscancode uint32          // Scancode identifying command\n\trepeat   bool            // Whether this is a repeat code\n}\n```\n\nTo send a command, you need to implement the following function. The\n`repeats` value should be zero to send a single command, or greater than\nzero to send one or more repeats for the command.\n\n```\nfunc (this *codec) Send(device uint32, scancode uint32, repeats uint) error {\n\tvar pulses[]uint32\n\n\t// Send a pulse and a space\n\tpulses = append(pulses, pulse_nanoseconds,space_nanoseconds)\n\n  // ...Continue to send pulses and spaces and end on a pulse...\n\n\t// Perform the pulse send\n\treturn this.lirc.PulseSend(pulses)\n}\n```\n\nYou can of course see the examples in the repository. The `codec` folder contains\nall of the implemented codecs so far. If you want to include your codec here, send\nme a pull request!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjthorpe%2Fremotes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjthorpe%2Fremotes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjthorpe%2Fremotes/lists"}