Is it possible to get Icecast metadata from HTML5 audio element? - javascript

I am using audio element to stream an ogg source from an icecast server. Does the audio element extract icy metadata and is there a way to access it through javascript?
Basically, I want to show "currently playing" information of a radio station I am streaming. What are my options?
Thanks!

No, your HTML5 elements are only aware of the stream data, and aren't even making the appropriate request to fetch the metadata.
See these posts:
Developing the client for the icecast server
Pulling Track Info From an Audio Stream Using PHP
http://www.smackfu.com/stuff/programming/shoutcast.html
Now, this isn't impossible by any means. You just have to do it server-side. (See that second link in particular.)
I should also point out that on a full-blown SHOUTcast Server (haven't tested with Icecast, but its worth a try) generates "7.html" which contains data on the number of listeners, max listeners, peak listeners, stereo/mono, bitrate, and current track name as comma-separated values. Like this:
2,1,33,625,2,128,J Mascis - Not Enough
If you can fetch http://yourstreamingserver:port/7.html, then you can get this data very easily.

In case of an Ogg container stream (So both Vorbis and Opus), at least Firefox supports javascript access to the metadata. This is currently only "vendor specific" Javascript API: audio.mozGetMetadata();
On the other hand if you go with Icecast 2.4.1 you can access metadata independently through a JSON API. Lack of synchronization as pointed out in other comments applies. It's usually "close enough" though.

Related

Inserting meta data into a live video stream

I want to achieve the following, but it remains unclear if this is possible.
The current scenario:
Someone is streaming a video with audio through
OBS to a media server, clients connect through a website.
[OBS Stream/Video Stream] -> [AWS/External Streaming Service] -> Clients
The wanted scenario:
capture this stream through a custom media server
and manipulate it by injecting certain metadata at certain moments
during the livestream. Note the importance of live.
[OBS Stream/Video Stream] -> [My Custom Node.js Server to insert metadata] -> [AWS/External Streaming Service] -> Clients
The idea:
The idea is that I want to synchronize the stream to some popup for example. The default protocol stream seems to be RTMP from OBS, but maybe this can be changed. At a given time during the livestream, an html5 videoplayer on the website can read these tags from the livestream (through some additional library such as video.js) and tell the JS application to show some text. In the end, it boils down to synchronizing the video stream to a text stream (eg from a websocket connection)
Potential solutions:
ID3 tags. I read about ID3 tags in MP3 files, but this does not seem to be what i'm looking as it needs a complete .mp3 file upfront and is not used for streams (Dynamically Inject ID3 in FFMPEG Live Stream). What I want is to dynamically inject metadata into this stream. For example, inject an id at any time (dynamically chosen) which references to a database for example should suffice.
LTC/Linear Time Code/SMPTE is this possible to embed that in a video stream somehow with node.js? that would enable me to match timings with an id on the client.
Is this possible to do given an incoming video stream with audio? and if so, what is the format of the stream and how do I inject metadata?
EDIT: it seems RTMP is not supported without flash in the browser. This is a no-go so I will need to use another stream format such as HLS/FLV?
Sounds like using something like Liquidsoap as your streaming server would do the trick for inserting the metadata into the stream. Plenty of options for manipulating metadata for you to explore.
As for client side decoding you could perhaps use a javascript readable stream within a service worker to split the server output into metadata/video and process as you see fit.
I did a similar thing for processing inband metadata on an infinite mp3 stream which might give you some ideas on where to start. You can find the code for that here

Acquire Video File Metadata From S3

Setup: I'm working on a video upload tool. I use a 3rd party javascript library that loads content from a users various storage locations (Hard Drive, Dropbox, Facebook, etc )
The library pushes the videos to our S3 bucket and returns the url of the uploaded file.
Goal: I would like to get the metadata (Height / Width / Duration / Etc) about the video without having to load the entire video binary.
Context: I use a service that handles video transcoding, and eventually posts the transcoded metadata to one of our backend servers. The transcoding can take a few minutes.
I need to get the temporary metadata of the uploaded file, but i don't want to load the full video.
Setting preload="metadata" on an HTML video tag means the browser is supposed to fetch metadata but not the whole stream. It's only considered a hint, i.e., browsers are not required to follow it, but you could try it and see if it works on the browsers you need to support. What it should do, I believe, is fetch just the first part of the video file, so it can read the header.
If that doesn't work, you probably need to implement a separate Ajax call to fetch the metadata. Hopefully your transcoding service gives you the metadata in a way that you can access it server-side. Otherwise you might need to extract it yourself, on the server. For example, you could use the ffmpeg library (or spawn an ffmpeg command line process) to parse out the metadata.

Sample Rate Conversion for Web Audio Streaming

I'm doing a project where I have a server offering up audio via WebSocket to the browser. The browser is then using WebSocket to capture the audio blocks and play them out via the Web Audio API.
I create an AudioContext which then has a predefined sample rate of X to play back this audio on the local hardware. Fair enough. However, the sample rate of the audio I am getting from the server is Y (which is not necessarily the same value as X, but I do know what it is via the WebSocket protocol I have defined).
After doing a lot of digging I can't seem to see a way in which the input audio would be resampled via Web Audio itself. I can't imagine this is an uncommon problem but since I'm not quite an expert JavaScript coder I have yet to discern the solution.
Just assigning the samples to getChannelData only really works when X==Y. Otherwise, the audio skips and is at the wrong pitch. Using decodeAudioData allows me access to do the resampling, it seems, but I don't want to have to write my own resampler.
Thoughts?
Confused, are you needing to use decodeAudioData?
If you just have the raw PCM data transferred, you just create an AudioBuffer in your local AudioContext at the served buffer's sampleRate (i.e. you set the third parameter of http://webaudio.github.io/web-audio-api/#widl-AudioContext-createBuffer-AudioBuffer-unsigned-long-numberOfChannels-unsigned-long-length-float-sampleRate based on the data you're getting), and call start() with an appropriate time (and a playbackRate of 1). You WILL get minor glitches at block boundaries, but only minor ones.
There's an active discussion on this, watch issue: https://github.com/WebAudio/web-audio-api/issues/118.

Feed video byte data to flash player from javascript?

Is it possible to, using javascript, either create video data on the fly, or more likely download pieces of video data from various sources and feed them to a flash player instance.
Even better, is it possible to feed a html5 video stream from locally executed javascript?
Short answer: no.
Long answer:
To pass the data directly from JavaScript into Flash, such as by ExternalInterface, you would need to serialize the video data as a byte stream. This means JS must be able to access video frame data, convert it to a String, and send it to Flash.
Serializing video data in the browser with JS would take some pretty fancy footwork; given the way HTML5 video works, I don't think any mainstream web browser supports this.
As a suggestion - you can use JS to feed URLs of video files to Flash where Flash can open the connection and access the data itself. In general Flash is vastly better at manipulating media data like videos and images. If you're already planning to using Flash you're better off cutting JS out of that process anyway.

YouTube API Question

What is the best way given the YouTube url to send the audio to a list view like (http://opentape.fm/mixtape/). I would have to it streaming from the YouTube player, rather than downloading and uploading the actual file to the server. Any help would be awesome, thanks!
The big problem you have here is that YouTube does not take mp3 files directly, a video must be created from the mp3 file.
Dynamically creating a video within the browser without any server-side assistance would be near impossible, it is hard enough to get data access to the mp3s (or any image source for the video stream) and writing a codec in JavaScript is not going to be fun.
You could probably do it server-side in a streaming fashion if you can find/write software that can chunk the mp3 audio appropriately and just shove a flat image in to a simple video stream on each key frame, multiplexing as you go.
Should you be able to do all that, the API details for uploading detail the process. You can do this without any metadata at all, simplifying the process somewhat for streaming.
But generally, the answer is no - not easy to do this client-side. You could make an AJAX service out of the server-side idea that takes a URL as a parameter, but that's about the limit.

Categories