MatijaL
Got stuck integrating PeerJS (WebRTC) with my LiveView app
Hi guys,
I’m trying to integrate PeerJS to my Phoenix LiveView App. So, I want to support video calling between users using WebRTC. This is a learning project and I have never done anything like this, there are many new concepts here that I don’t fully understand so naturally, I got stuck.
So, first a user creates a talk, then a show template is rendered where videos should show. Video from a user shows fine, but I’m not sure how to connect it to another user inside a talk.
Can anyone help?
show.ex
defmodule MyAppWeb.TalkLive.Show do
use MyAppWeb, :live_view
alias MyApp.Accounts
alias MyApp.Profiles
alias MyApp.Talks
alias MyAppWeb.Presence
alias Phoenix.Socket.Broadcast
@impl true
def mount(%{"slug" => slug}, %{"user_token" => user_token} = _session, socket) do
current_user = Accounts.get_user_by_session_token(user_token)
profile = Profiles.get_profile!(current_user.id)
if connected?(socket) do
Phoenix.PubSub.subscribe(MyApp.PubSub, "talk:" <> slug)
Phoenix.PubSub.subscribe(MyApp.PubSub, "talk:" <> slug <> ":" <> to_string(current_user.id))
{:ok, _} = Presence.track_talk_user(self(), "talk:" <> slug, current_user, profile)
end
case Talks.get_talk(slug) do
nil ->
{:ok,
socket
|> assign(:current_user, current_user)
|> assign(:profile, profile)
|> put_flash(:error, "That Talk does not exist.")
|> push_navigate(to: ~p"/talks/new")
}
talk ->
{:ok,
socket
|> assign(:current_user, current_user)
|> assign(:profile, profile)
|> assign(:talk, talk)
|> assign(:online_users, list_online_users(talk))
}
end
end
@impl true
def handle_info(%Broadcast{event: "presence_diff"}, socket) do
talk = socket.assigns.talk
{:noreply,
socket
|> assign(:online_users, list_online_users(talk))}
end
defp list_online_users(talk) do
Presence.list("talk:" <> talk.slug)
|> Enum.map(fn {_k, %{metas: [v]}} -> v end)
end
end
show.html.heex
<div class="flex">
<div id="video-grid" class="">
<video id="local-video" class="rotate-video" playsinline autoplay muted class="w-1/2 bg-red-800"></video>
<div class=""><%= @profile.username %></div>
</div>
<%= for user <- @online_users do %>
<%= unless user.user_id == @current_user.id do %>
<div class="">
<video id={"remote-video-#{user.user_id}"} data-user-id={user.user_id} playsinline autoplay class="w-96 bg-green-800"></video>
<div class=""><%= user.username %></div>
</div>
<% end %>
<% end %>
</div>
<.button id="join-call" phx-hook="JoinCall" data-user-id={@current_user.id}>Join Call</.button>
app.js
let Hooks = {}
Hooks.JoinCall = {
mounted() {
console.log("Connected to Call")
const currentUserId = "bljeeee-" + this.el.dataset.userId
console.log(this.el.dataset)
console.log("Current User ID: ", currentUserId)
const videoGrid = document.getElementById("video-grid")
const localVideo = document.getElementById("local-video")
const remoteVideo = document.getElementById("remote-video")
async function initStream() {
try {
var peer = new Peer();
peer.on("open", id => {
console.log("Peer ID: ", id)
})
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(stream => {
addVideoStream(localVideo, stream)
})
} catch (e) {
console.log("JoinCall ERROR")
console.log(e)
}
}
this.el.addEventListener("click", e => {
initStream()
})
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener("loadedmetadata", () => {
video.play
})
videoGrid.append(video)
}
}
}
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, hooks: Hooks})
Popular in Questions
Hi,
I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
Hi,
I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
How to bind a phoenix app to a specific ip address?
could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
Hi there,
I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Lets say I have map like this fetching from my database
%{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Hi!
Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
Other popular topics
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine)
This is a plugin that adds support for Elixir to JetBrains IntelliJ...
New
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition)
It’s been a while since we first asked this, I...
New
Hi there,
I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Got a question about when to concat vs. prepending items to list then reversing to achieve appending.
So i know lists boil down to [1 | ...
New
Hello all!
I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









