{"id":25206739,"url":"https://github.com/sudo-self/pytr","last_synced_at":"2026-02-06T23:01:19.757Z","repository":{"id":276234183,"uuid":"928661758","full_name":"sudo-self/pytr","owner":"sudo-self","description":"instant ringtones for Apple \u0026 Android devices","archived":false,"fork":false,"pushed_at":"2025-02-27T03:47:44.000Z","size":2588,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-19T05:22:33.427Z","etag":null,"topics":["huggingface-spaces","instant","ringtones"],"latest_commit_sha":null,"homepage":"https://sudo-self.github.io/pytr/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sudo-self.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2025-02-07T02:22:33.000Z","updated_at":"2025-02-27T03:47:47.000Z","dependencies_parsed_at":"2025-07-19T02:39:24.494Z","dependency_job_id":null,"html_url":"https://github.com/sudo-self/pytr","commit_stats":null,"previous_names":["sudo-self/pytr"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sudo-self/pytr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-self%2Fpytr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-self%2Fpytr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-self%2Fpytr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-self%2Fpytr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sudo-self","download_url":"https://codeload.github.com/sudo-self/pytr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudo-self%2Fpytr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29179563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T22:12:24.066Z","status":"ssl_error","status_checked_at":"2026-02-06T22:12:09.859Z","response_time":59,"last_error":"SSL_read: 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":["huggingface-spaces","instant","ringtones"],"created_at":"2025-02-10T11:18:02.089Z","updated_at":"2026-02-06T23:01:19.740Z","avatar_url":"https://github.com/sudo-self.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\ntitle: PYTR\nemoji: 🎵\ncolorFrom: red\ncolorTo: indigo\nsdk: gradio\nsdk_version: 5.15.0\napp_file: app.py\npinned: false\nlicense: apache-2.0\n---\n\n## on hugging face \u003ca href=\"https://huggingface.co/spaces/sudo-soldier/PYTR\"\u003ePYTR\u003c/a\u003e\u003cbr /\u003e\n\n**Framework:** Gradio (v5.15.0)  \n**License:** Apache 2.0  \n  \n\n## Run Locally  \n\n```\ngit clone https://huggingface.co/spaces/sudo-soldier/PYTR\n```\n\n```\ncd PYTR\n```\n\n## Create and activate Python environment\n```\npython -m venv env\nsource env/bin/activate\n```\n\n## Install dependencies and run\n```\npip install -r requirements.txt\npython app.py\n```\n\n## Embed the space\n```\n\u003ciframe \n  src=\"https://sudo-soldier-pytr.hf.space\" \n  frameborder=\"0\" \n  width=\"850\" \n  height=\"450\"\u003e\n\u003c/iframe\u003e\n```\n\n## app.py\n\n```\n\nimport os\nimport yt_dlp\nimport gradio as gr\nimport re\nimport subprocess\nfrom pydub import AudioSegment\n\nos.makedirs(\"downloads\", exist_ok=True)\n\ndef sanitize_filename(filename):\n    \"\"\"Sanitize filenames by replacing special characters.\"\"\"\n    return re.sub(r'[^a-zA-Z0-9_-]', '_', filename)\n\ndef process_youtube_or_audio(url, uploaded_audio, start_time, end_time):\n    \"\"\"Downloads or processes audio, trims it, and exports ringtones.\"\"\"\n    try:\n        filename, song_name = None, None\n\n        if url:\n            ydl_opts = {\n                'format': 'bestaudio/best',\n                'outtmpl': 'downloads/%(title)s.%(ext)s',\n                'cookiefile': 'cookies.txt'\n            }\n            with yt_dlp.YoutubeDL(ydl_opts) as ydl:\n                info = ydl.extract_info(url, download=True)\n                filename = ydl.prepare_filename(info)\n                song_name = sanitize_filename(info['title'])\n        \n        elif uploaded_audio is not None:\n            filename = uploaded_audio\n            song_name = sanitize_filename(os.path.splitext(os.path.basename(uploaded_audio))[0])\n        \n        if not filename or not os.path.exists(filename):\n            return None, None\n\n        audio = AudioSegment.from_file(filename)\n        start_ms, end_ms = int(start_time * 1000), int(end_time * 1000)\n        start_ms = max(0, min(start_ms, len(audio)))\n        end_ms = max(start_ms, min(end_ms, len(audio)))\n\n        trimmed_audio = audio[start_ms:end_ms]\n\n        mp3_filename = f\"downloads/{song_name}.mp3\"\n        trimmed_audio.export(mp3_filename, format=\"mp3\")\n\n        m4a_filename = f\"downloads/{song_name}.m4a\"\n        result = subprocess.run([\n            'ffmpeg', '-y', '-i', mp3_filename, '-vn', '-acodec', 'aac', '-b:a', '192k', m4a_filename\n        ], capture_output=True, text=True)\n\n        if result.returncode != 0 or not os.path.exists(m4a_filename):\n            print(\"FFmpeg Error:\", result.stderr)\n            return mp3_filename, None\n\n        m4r_filename = f\"downloads/{song_name}.m4r\"\n        os.rename(m4a_filename, m4r_filename)\n\n        return mp3_filename, m4r_filename\n\n    except Exception as e:\n        print(f\"Error: {e}\")\n        return None, None\n\n# Gradio Interface\nwith gr.Blocks() as interface:\n    gr.HTML(\"\"\"\n        \u003ch1\u003e\u003ci class=\"fas fa-music\"\u003e\u003c/i\u003e\u0026nbsp;PYTR - Python YouTube Ringtones\u003c/h1\u003e\n        \u003cp\u003eEnter a YouTube URL or upload an audio file to create ringtones.\u003c/p\u003e\n        \u003cp\u003e\u003ca href=\"https://ringtones.jessejesse.xyz\"\u003eRingtones\u003c/a\u003e\u003c/p\u003e\n        \u003cp\u003e\u003ca href=\"https://github.com/sudo-self/pytr\"\u003eGitHub\u003c/a\u003e\u003c/p\u003e\n    \"\"\")\n\n    with gr.Row():\n        youtube_url = gr.Textbox(placeholder=\"Enter the URL here...\", label=\"YouTube URL\")\n        uploaded_audio = gr.File(label=\"Upload Audio File\", type=\"filepath\")\n\n    with gr.Row():\n        instructions = gr.Textbox(\n            value=\"Android: move the download to the 'Ringtones' folder.\\nApple: import download with 'Garage Band' and export to ringtones.\",\n            label=\"Install Ringtones\",\n            interactive=False\n        )\n\n    gr.HTML(\"\u003ch3\u003eTrim Audio\u003c/h3\u003e\")\n    with gr.Row():\n        start_time = gr.Slider(0, 20, value=0, label=\"Start Time (seconds)\")\n        end_time = gr.Slider(1, 20, value=20, label=\"End Time (seconds)\")\n    \n    process_button = gr.Button(\"Create Ringtones\")\n    \n    with gr.Row():\n        mp3_download = gr.File(label=\"Android Ringtone\")\n        iphone_ringtone = gr.File(label=\"iPhone Ringtone\")\n    \n    process_button.click(process_youtube_or_audio, inputs=[youtube_url, uploaded_audio, start_time, end_time], outputs=[mp3_download, iphone_ringtone])\n\ninterface.launch(share=True)\n\n```\n\n\u003cimg width=\"1440\" alt=\"Screenshot 2025-02-07 at 10 56 21\" src=\"https://github.com/user-attachments/assets/46ac4811-b978-4829-8bcc-81ea184d5ee4\" /\u003e\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudo-self%2Fpytr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsudo-self%2Fpytr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudo-self%2Fpytr/lists"}