{"id":18352762,"url":"https://github.com/membraneframework/membrane_tee_plugin","last_synced_at":"2025-12-12T00:26:24.208Z","repository":{"id":40302488,"uuid":"179053516","full_name":"membraneframework/membrane_tee_plugin","owner":"membraneframework","description":"Membrane plugin for splitting data from a single input to multiple outputs","archived":false,"fork":false,"pushed_at":"2023-11-17T14:44:36.000Z","size":122,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-18T10:53:52.834Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/membraneframework.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":"2019-04-02T10:24:15.000Z","updated_at":"2022-03-03T11:56:40.000Z","dependencies_parsed_at":"2023-07-12T15:45:06.616Z","dependency_job_id":"fcf849e7-1acf-4762-b24b-348682d4cb87","html_url":"https://github.com/membraneframework/membrane_tee_plugin","commit_stats":{"total_commits":92,"total_committers":16,"mean_commits":5.75,"dds":0.6521739130434783,"last_synced_commit":"2d954334001e7f3ebfe4b2fc55d54fda68e4c905"},"previous_names":["membraneframework/membrane-element-tee"],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/membraneframework%2Fmembrane_tee_plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/membraneframework%2Fmembrane_tee_plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/membraneframework%2Fmembrane_tee_plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/membraneframework%2Fmembrane_tee_plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/membraneframework","download_url":"https://codeload.github.com/membraneframework/membrane_tee_plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247478152,"owners_count":20945258,"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":[],"created_at":"2024-11-05T21:37:14.554Z","updated_at":"2025-12-12T00:26:24.175Z","avatar_url":"https://github.com/membraneframework.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Membrane Tee Plugin\n\n[![Hex.pm](https://img.shields.io/hexpm/v/membrane_tee_plugin.svg)](https://hex.pm/packages/membrane_tee_plugin)\n[![API Docs](https://img.shields.io/badge/api-docs-yellow.svg?style=flat)](https://hexdocs.pm/membrane_tee_plugin)\n[![CircleCI](https://circleci.com/gh/membraneframework/membrane_tee_plugin.svg?style=svg)](https://circleci.com/gh/membraneframework/membrane_tee_plugin)\n\nThis package provides elements that can be used to branch stream processing in pipeline, e.g. send data from one source to two or more sinks.\n\n## Installation\n\nThis package can be installed by adding `membrane_tee_plugin` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n\t{:membrane_tee_plugin, \"~\u003e 0.12.0\"}\n  ]\nend\n```\n\nThe docs can be found at [HexDocs](https://hexdocs.pm/membrane_tee_plugin).\n\n## Examples\n\n### `Membrane.Tee.Parallel`\n\nThis element has dynamic `:output` pads working in `:pull` mode. Packets are forwarded\nonly when all output pads send demands, which means that the slowest output pad dictates\nthe speed of processing data.\n\nPlaying this pipeline should result in copying the source file to all destination files (sinks).\nBefore playing it, make sure that the source file exists, e.g. like this:\n`echo \"Membrane Framework is cool\" \u003e /tmp/source_text_file`\n\nYou also need [`:membrane_file_plugin`](https://github.com/membraneframework/membrane_file_plugin) in project dependencies to run this pipeline.\n\n```elixir\ndefmodule FileMultiForwardPipeline do\n  use Membrane.Pipeline\n  alias Membrane.{File, Tee}\n\n  @impl true\n  def handle_init(_ctx, _state) do\n\n    links = [\n      child(:tee, Tee.Parallel),\n      child(file_src, %File.Source{location: \"/tmp/source_text_file\"}) \n      |\u003e get_child(:tee) |\u003e child(:file_sink1, %File.Sink{location: \"/tmp/destination_file1\"}),\n      get_child(:tee) |\u003e child(:file_sink2, %File.Sink{location: \"/tmp/destination_file2\"})\n    ]\n\n    {[spec: links], %{}}\n  end\nend\n```\n\n### `Membrane.Tee.PushOutput`\n\nThis element works like `Membrane.Tee.Parallel` but doesn't care about the speed of processing of elements connected to its outputs.\nIf such an element doesn't process data fast enough, it crashes with the toilet overflow error. In other words, the input pad dictates\nthe speed of processing.\n\n### `Membrane.Tee.Master`\n\nThis element has one `:master` output pad that dictates the speed of processing data\nand dynamic `:copy` pad working in `:push` mode mirroring `:master` pad.\n\nPlaying this pipeline should result in playing mp3 source file and copying it to the destination file.\nBefore playing it, make sure you have valid source file, e.g. [this one](https://github.com/membraneframework/membrane-demo/blob/v0.3/sample.mp3).\n\nYou also need [`:membrane_file_plugin`](https://github.com/membraneframework/membrane_file_plugin) and [`:membrane_portaudio_plugin`](https://github.com/membraneframework/membrane_portaudio_plugin) in project dependencies to run this pipeline.\n\n```elixir\ndefmodule AudioPlayAndCopyPipeline do\n  use Membrane.Pipeline\n  alias Membrane.{File, Tee, PortAudio}\n\n  @impl true\n  def handle_init(_ctx, _opts) do\n    links = [\n      child(:tee, Tee.Master),\n      child(:file_src, %File.Source{location: \"/tmp/source_file.mp3\"}) |\u003e get_child(:tee),\n      get_child(:tee) |\u003e via_out(:master) |\u003e child(:audio_sink,PortAudio.Sink),\n      get_child(:tee) |\u003e via_out(:copy) |\u003e to(:file_sink,%File.Sink{location: \"/tmp/destination_file.mp3\"})\n    ]\n\n    {[spec: links], %{}}\n  end\nend\n```\n\n## Copyright and License\n\nCopyright 2019, [Software Mansion](https://swmansion.com/?utm_source=git\u0026utm_medium=readme\u0026utm_campaign=membrane_tee_plugin)\n\n[![Software Mansion](https://logo.swmansion.com/logo?color=white\u0026variant=desktop\u0026width=200\u0026tag=membrane-github)](https://swmansion.com/?utm_source=git\u0026utm_medium=readme\u0026utm_campaign=membrane_tee_plugin)\n\nLicensed under the [Apache License, Version 2.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmembraneframework%2Fmembrane_tee_plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmembraneframework%2Fmembrane_tee_plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmembraneframework%2Fmembrane_tee_plugin/lists"}