{"id":21658389,"url":"https://github.com/tsirysndr/upnp-client-rs","last_synced_at":"2025-04-11T22:33:52.246Z","repository":{"id":65591270,"uuid":"594780849","full_name":"tsirysndr/upnp-client-rs","owner":"tsirysndr","description":"This is a UPnP client library for Rust.","archived":false,"fork":false,"pushed_at":"2024-06-07T06:08:05.000Z","size":50,"stargazers_count":24,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T18:40:25.778Z","etag":null,"topics":["dlna","dlna-upnp","network-programming","rust","tokio","upnp"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/tsirysndr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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},"funding":{"github":"tsirysndr","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":[]}},"created_at":"2023-01-29T16:17:29.000Z","updated_at":"2024-11-16T08:20:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"3cedd557-0b70-4453-afc9-a6cfb49af831","html_url":"https://github.com/tsirysndr/upnp-client-rs","commit_stats":{"total_commits":27,"total_committers":2,"mean_commits":13.5,"dds":0.2592592592592593,"last_synced_commit":"bbcfce2e53776ebea5ad7cffd892cab8fd065485"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsirysndr%2Fupnp-client-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsirysndr%2Fupnp-client-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsirysndr%2Fupnp-client-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsirysndr%2Fupnp-client-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsirysndr","download_url":"https://codeload.github.com/tsirysndr/upnp-client-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248490283,"owners_count":21112720,"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":["dlna","dlna-upnp","network-programming","rust","tokio","upnp"],"created_at":"2024-11-25T09:29:13.141Z","updated_at":"2025-04-11T22:33:52.223Z","avatar_url":"https://github.com/tsirysndr.png","language":"Rust","funding_links":["https://github.com/sponsors/tsirysndr"],"categories":["Rust"],"sub_categories":[],"readme":"\u003ch1\u003eUPnP Client\u003c/h1\u003e\n\u003cp\u003e\n  \u003ca href=\"LICENSE\" target=\"_blank\"\u003e\n    \u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/License-MIT-blue.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/upnp-client\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/v/upnp-client.svg\" /\u003e\n  \u003c/a\u003e\n  \n  \u003ca href=\"https://crates.io/crates/upnp-client\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/dr/upnp-client\" /\u003e\n  \u003c/a\u003e\n  \n  \u003ca href=\"https://docs.rs/upnp-client\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://docs.rs/upnp-client/badge.svg\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nThis is a UPNP client library for Rust.\n\n### Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nupnp-client = \"0.1\"\n```\n\n### Example\n\nThis example will print out all the devices found on the network.\n\n```rust\nuse colored_json::prelude::*;\nuse futures_util::StreamExt;\n\nuse crate::discovery::discover_pnp_locations;\n\nmod discovery;\nmod types;\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let devices = discover_pnp_locations().await?;\n    tokio::pin!(devices);\n\n    while let Some(device) = devices.next().await {\n        let json = serde_json::to_string_pretty(\u0026device)?;\n        println!(\"{}\", json.to_colored_json_auto()?);\n    }\n\n    Ok(())\n}\n```\n\nOutput:\n\n```json\n{\n  \"device_type\": \"urn:schemas-upnp-org:device:MediaRenderer:1\",\n  \"friendly_name\": \"Kodi (MacBook-Pro-de-Tsiry-4.local)\",\n  \"location\": \"http://192.168.8.101:1825/\",\n  \"manufacturer\": \"XBMC Foundation\",\n  \"manufacturer_url\": \"http://kodi.tv/\",\n  \"model_description\": \"Kodi - Media Renderer\",\n  \"model_name\": \"Kodi\",\n  \"model_number\": \"18.4 Git:20190831-3ade758ceb\",\n  \"services\": [\n    {\n      \"control_url\": \"/AVTransport/d599320b-2d3b-e0d7-3224-dc1c4b074dae/control.xml\",\n      \"event_sub_url\": \"/AVTransport/d599320b-2d3b-e0d7-3224-dc1c4b074dae/event.xml\",\n      \"scpd_url\": \"/AVTransport/d599320b-2d3b-e0d7-3224-dc1c4b074dae/scpd.xml\",\n      \"service_id\": \"urn:upnp-org:serviceId:AVTransport\",\n      \"service_type\": \"urn:schemas-upnp-org:service:AVTransport:1\"\n    },\n    {\n      \"control_url\": \"/ConnectionManager/d599320b-2d3b-e0d7-3224-dc1c4b074dae/control.xml\",\n      \"event_sub_url\": \"/ConnectionManager/d599320b-2d3b-e0d7-3224-dc1c4b074dae/event.xml\",\n      \"scpd_url\": \"/ConnectionManager/d599320b-2d3b-e0d7-3224-dc1c4b074dae/scpd.xml\",\n      \"service_id\": \"urn:upnp-org:serviceId:ConnectionManager\",\n      \"service_type\": \"urn:schemas-upnp-org:service:ConnectionManager:1\"\n    },\n    {\n      \"control_url\": \"/RenderingControl/d599320b-2d3b-e0d7-3224-dc1c4b074dae/control.xml\",\n      \"event_sub_url\": \"/RenderingControl/d599320b-2d3b-e0d7-3224-dc1c4b074dae/event.xml\",\n      \"scpd_url\": \"/RenderingControl/d599320b-2d3b-e0d7-3224-dc1c4b074dae/scpd.xml\",\n      \"service_id\": \"urn:upnp-org:serviceId:RenderingControl\",\n      \"service_type\": \"urn:schemas-upnp-org:service:RenderingControl:1\"\n    }\n  ]\n}\n```\n\n## Streaming\n\n```rust\nuse futures_util::StreamExt;\nuse upnp_client::{\n    device_client::DeviceClient,\n    discovery::discover_pnp_locations,\n    media_renderer::MediaRendererClient,\n    types::{Device, LoadOptions, Metadata, ObjectClass},\n};\n\nconst KODI_MEDIA_RENDERER: \u0026str = \"Kodi - Media Renderer\";\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let devices = discover_pnp_locations().await?;\n    tokio::pin!(devices);\n\n    let mut kodi_device: Option\u003cDevice\u003e = None;\n    while let Some(device) = devices.next().await {\n        // Select the first Kodi device found\n        if device.model_description == Some(KODI_MEDIA_RENDERER.to_string()) {\n            kodi_device = Some(device);\n            break;\n        }\n    }\n\n    let kodi_device = kodi_device.unwrap();\n    let device_client = DeviceClient::new(\u0026kodi_device.location)?.connect().await?;\n    let media_renderer = MediaRendererClient::new(device_client);\n\n    let options = LoadOptions {\n        dlna_features: Some(\n            \"DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000\"\n                .to_string(),\n        ),\n        content_type: Some(\"video/mp4\".to_string()),\n        metadata: Some(Metadata {\n            title: \"Big Buck Bunny\".to_string(),\n            ..Default::default()\n        }),\n        autoplay: true,\n        object_class: Some(ObjectClass::Video),\n        ..Default::default()\n    };\n\n    let media_url =\n        \"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4\";\n\n    media_renderer.load(media_url, options).await?;\n\n    Ok(())\n}\n\n\n```\n\nSee the [examples](./examples) directory for more examples.\n\n### Features\n\n- [x] Discover devices\n- [x] Control Media Renderer device (Load, Play, Pause, Stop, Seek, etc.)\n- [x] Browse Media Server device\n\n\n### References\n- [UPnP Device Architecture 1.1](http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf)\n- [UPnP AVTransport v3 Service](http://www.upnp.org/specs/av/UPnP-av-AVTransport-v3-Service-20101231.pdf)\n- [UPnP AV ContentDirectory v3 Service](http://upnp.org/specs/av/UPnP-av-ContentDirectory-v3-Service.pdf)\n\n### License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsirysndr%2Fupnp-client-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsirysndr%2Fupnp-client-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsirysndr%2Fupnp-client-rs/lists"}