{"id":37072260,"url":"https://github.com/radusuciu/traktor_nowplaying","last_synced_at":"2026-01-14T08:29:05.811Z","repository":{"id":54145951,"uuid":"260770344","full_name":"radusuciu/traktor_nowplaying","owner":"radusuciu","description":"A cross-platform library and command-line tool that extracts the currently playing track in Traktor and optionally outputs to a file with configurable formatting.","archived":false,"fork":false,"pushed_at":"2023-03-16T15:48:22.000Z","size":244,"stargazers_count":64,"open_issues_count":2,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-09-01T03:08:29.857Z","etag":null,"topics":["command-line-tool","library","metadata-extraction","nowplaying","traktor"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/radusuciu.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}},"created_at":"2020-05-02T20:34:36.000Z","updated_at":"2025-04-29T12:37:56.000Z","dependencies_parsed_at":"2022-08-13T07:31:27.580Z","dependency_job_id":null,"html_url":"https://github.com/radusuciu/traktor_nowplaying","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/radusuciu/traktor_nowplaying","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radusuciu%2Ftraktor_nowplaying","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radusuciu%2Ftraktor_nowplaying/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radusuciu%2Ftraktor_nowplaying/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radusuciu%2Ftraktor_nowplaying/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/radusuciu","download_url":"https://codeload.github.com/radusuciu/traktor_nowplaying/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radusuciu%2Ftraktor_nowplaying/sbom","scorecard":{"id":758028,"data":{"date":"2025-08-11","repo":{"name":"github.com/radusuciu/traktor_nowplaying","commit":"f070a4afe3cd1748acbcb14377075831110c07b4"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.1,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:83: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:97: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:108: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:114: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:120: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:126: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:133: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:142: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:152: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:162: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:172: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/radusuciu/traktor_nowplaying/release.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:28","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:57","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:58","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:177","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:178","Info:   0 out of  18 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   6 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.3.5 not signed: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/95866500","Warn: release artifact v0.3.4 not signed: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/39411221","Warn: release artifact v0.3.3 not signed: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/30949990","Warn: release artifact v0.3.2 not signed: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/30948111","Warn: release artifact v0.3.1 not signed: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/30943923","Warn: release artifact v0.3.5 does not have provenance: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/95866500","Warn: release artifact v0.3.4 does not have provenance: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/39411221","Warn: release artifact v0.3.3 does not have provenance: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/30949990","Warn: release artifact v0.3.2 does not have provenance: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/30948111","Warn: release artifact v0.3.1 does not have provenance: https://api.github.com/repos/radusuciu/traktor_nowplaying/releases/30943923"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-22T22:22:00.185Z","repository_id":54145951,"created_at":"2025-08-22T22:22:00.185Z","updated_at":"2025-08-22T22:22:00.185Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28414032,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:16:59.381Z","status":"ssl_error","status_checked_at":"2026-01-14T08:13:45.490Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["command-line-tool","library","metadata-extraction","nowplaying","traktor"],"created_at":"2026-01-14T08:29:05.253Z","updated_at":"2026-01-14T08:29:05.802Z","avatar_url":"https://github.com/radusuciu.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![PyPI pyversions](https://img.shields.io/pypi/pyversions/traktor-nowplaying.svg)](https://pypi.python.org/pypi/traktor-nowplaying/)\n[![PyPI version fury.io](https://img.shields.io/pypi/v/traktor-nowplaying.svg)](https://pypi.python.org/pypi/traktor-nowplaying/)\n[![GitHub release](https://img.shields.io/github/release/radusuciu/traktor_nowplaying.svg)](https://github.com/radusuciu/traktor_nowplaying/releases/)\n\n# Traktor Now Playing\n\nThis project for Python 3 (tested on 3.6+) uses Traktor's broadcast functionality to extract metadata about the currently playing song. This is really a very thin wrapper around some [tinytag](https://github.com/devsnd/tinytag) methods that can be found in `ogg.py`, where the original license is also included. There are no dependencies. Tested with Traktor 3.3, but this will likely work with older versions as well.\n\nThe reason this exists is because it's rather difficult to get this information through other means. You can [use MIDI](https://github.com/Sonnenstrahl/traktor-now-playing) for this as well, but that requires that you add a fake controller.\n\nLastly, there are several other projects that do something similar such as [Traktor Metadata Listener](https://www.disconova.com/utu/traktor-metadata/) which is not open-source and likely will never be, and [traktor-now-playing](https://github.com/Sonnenstrahl/traktor-now-playing), which uses the MIDI approach mentioned above.\n\n## Installation\n\nThe preferred installation method is via [pip](https://pip.pypa.io/en/stable/):\n\n```bash\npip install traktor_nowplaying\n```\n\nThere are also binary releases available for Windows, Linux, and MacOS. These are created using `pyInstaller` and GitHub actions and can be downloaded from [the project Releases page](https://github.com/radusuciu/traktor_nowplaying/releases).\n\n## General use\n\nIn order for this program to work, you of course have to setup the broadcasting feature of Traktor - note that this completely hijacks that functinality, so while you can still record and broadcast through some other means (eg. using a splitter or other outputs on your controller/mixer, or [from the recording itself](https://radusuciu.com/posts/broadcasting-from-traktor-an-alternative-to-the-built-in-broadcasting-function/)), you cannot broadcast from Traktor itself.\n\nYou must configure Traktor to broadcast to `localhost` and the port specified with the `-p`, or `--port` option (defaults to `8000`), or the port that is passed to the constructor if you're using this as a library instead. For the format setting you can use anything, but I recommend choosing the lowest bitrate for the sample rate of your system, so most commonly the best choice is 44100 Hz, 64 Kbps.\n\nNote that there is a delay between when you change a song in Traktor and when the change is picked up.\n\n## Use from command line\n\nIf you run the program without specifying any options you'll be asked if you want to set the options interactively, or you can hit enter which uses all default options, which are to listen on port `8000`, and output the currently playing song to the console:\n```bash\ntraktor_nowplaying\n```\n\nListen on port `8000`, output to `nowplaying.txt` in the current directory and do not output to `stdout`:\n```bash\ntraktor_nowplaying --port 8000 --outfile='nowplaying.txt' --quiet\n```\n\nThe help text:\n```\n$ traktor_nowplaying --help\nusage: traktor_nowplaying [-h] [-p PORT] [-q] [-f FORMAT] [-o OUTFILE]\n                          [-t TEMPLATE] [-a] [-m MAX_TRACKS] [-i] [-v]\n\nUse Traktor's broadcast functionality to extract metadata about the currently\nplaying song\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -p PORT, --port PORT  Port to listen on for broadcasts from Traktor\n  -q, --quiet           Suppress console output of currently playing song\n  -f FORMAT, --format FORMAT\n                        Custom format to use when outputting tracks\n  -o OUTFILE, --outfile OUTFILE\n                        Provide a file path to which the currently playing song\n                        should be written\n  -t TEMPLATE, --template TEMPLATE\n                        Template file to use for output. Templating is\n                        implemented using Bottle SimpleTemplate\n                        (https://bottlepy.org/docs/0.12/stpl.html). See README\n                        for more details on use. Note: the --format options is\n                        ignored when using a custom template file. Take care\n                        when using templates provided by others on the internet\n                        as they can contain malicious code.\n  -a, --append          If writing to file, appends newest track to end of file\n                        instead of overwriting the file\n  -m MAX_TRACKS, --max-tracks MAX_TRACKS\n                        If appending to a file, the maximum number of tracks to\n                        keep in file (by default there is no limit)\n  -i, --interactive     Interactive mode allows for settings to be specified at\n                        runtime. These override command line options.\n  -v, --version         show program's version number and exit\n\nNote that you must configure Traktor to broadcast to localhost and the port\nspecified with the -p, or --port option (defaults to 8000). For the format\nsetting you can use anything, but I recommend choosing the lowest bitrate for\nthe sample rate of your system, so most commonly the best choice is 44100 Hz,\n64 Kbps.\n```\n\nTo stop the process `Ctrl + C` should suffice.\n\n## Using binary releases\n\nIf you've downloded a platform specific release from [the Releases page](https://github.com/radusuciu/traktor_nowplaying/releases), the use instructions are the same as described above for the command-line.\n\n## Use as a library\n\n`traktor_nowplaying` can also be used as a library. This can be useful if you'd like to leverage this rather simple functionality in other code.\n\n```python\nfrom traktor_nowplaying import Listener\n\nlistener = Listener(port=8000, quiet=True, outfile='nowplaying.txt')\nlistener.start()\n```\n\nFor a more elaborate example with a custom callback, see this project: https://github.com/radusuciu/traktor_ice, and [this bit](https://github.com/radusuciu/traktor_ice/blob/b0873cb5e36dbcb87a260900f44a2f1768d5d5c9/traktor_ice/core.py#L60-L74) in particular.\n\n## Customizing output\n\nThe output of `traktor_nowplaying` can be customized using the `--format` and `--template` options. Both of these functions make use of the [`SimpleTemplate` Engine](https://bottlepy.org/docs/0.12/stpl.html) included with [Bottle 0.12](https://bottlepy.org/docs/0.12/), so anything you can use with Bottle's templates, you can use here.\n\n**Note**: Please take care when using format strings or templates provided by others on the internet. These can contain malicious code. I doubt this will be the case since this is such an obscure project and I can't imagine templates being complex enough to hide malware, but you never know.\n\n### `--format`\n\nThis option allows for the specification of alternate ways to display tracks. By default, tracks are formatted using a simple template: `{{artist}} - {{title}}`. You can change the order: `{{title}} - {{artist}}`, only display the title `{{title}}`, or sprinkle in some HTML: `\u003cp\u003e\u003cstrong\u003e{{artist}}\u003c/strong\u003e - {{title}}`.\n\n### `--template`\n\nWhile `--format` allows you to control the display of each individual track, `--template` allows you to specify a template file. This template file will be passed a `tracks` variable that contains a list of tracks to display. Each individual track is a Python `dict` with `artist` and `title` keys. Here's an example:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003cmeta charset=\"UTF-8\"\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        % for track in tracks:\n        \u003cp\u003e\u003cstrong\u003e{{track.get('artist', '')}}\u003c/strong\u003e - {{track.get('title', '')}}\u003c/p\u003e\n        % end\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nIf you save the above as `template.html` you can use it like so: `traktor_nowplaying --template template.html --append`. Note that without setting `--append`, you will only have the latest track being output.\n\n**Note**: Templates don't have to be HTML\n\n**Note**: `--template` overrides `--format`.\n\n## Development\n\nSome notes, mostly for myself about developing traktor_nowplaying.\n\n### Releasing\n\nBinary releases are created using [pysinstaller](https://www.pyinstaller.org/) and the following command:\n\n```bash\npyinstaller traktor_nowplaying/cli.py -n traktor_nowplaying --onefile --icon=assets/icon.ico\n```\n\nThese are automatically handled by GitHub actions, which are triggered when a new tag is pushed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradusuciu%2Ftraktor_nowplaying","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fradusuciu%2Ftraktor_nowplaying","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradusuciu%2Ftraktor_nowplaying/lists"}