I was reading a article on soundcloud today about their waveforms and how they generate them by converting the highest volume point into a INT between 0 - 1.
After that I opened the console on chrome and then a track on Soundcloud, going through the networks tab (all files) there was no file returning a array of data to generate the html5 waveform, so my question is how do they do it without requesting the data?
Interesting question :) I'm no expert at HTML5's canvas, but I'm sure it has to do with that.
If you look at the DOM you'll see a structure like this:
<div class="sound__body">
<div class="sound__waveform">
<div class="waveform loaded">
<div class="waveform__layer waveform__scene">
<canvas aria-hidden="true" class="g-box-full sceneLayer" width="453" height="60"></canvas>
<canvas aria-hidden="true" class="g-box-full sceneLayer waveformCommentsNode loaded" width="453" height="60"></canvas>
<canvas aria-hidden="true" class="g-box-full sceneLayer" width="453" height="60"></canvas>
</div>
<div class="commentPlaceholder g-z-index-content">...</div>
<div class="commentPopover darkText smallAvatar small">...</div>
</div>
</div>
</div>
On my page I have four sounds. In my networkpanel I also have four of these:
https://wis.sndcdn.com/iGZOEq0vuemr_m.png
They are being sent as JSON, not as PNG!
And contain stuff like:
{"width":1800,"height":140,"samples":
[111,116,118,124,121,121,116,103,119,120,118,118,119,123,128,128,119,119,119,120,117,116,123,127,124,119,115,120,120,121,120,120,121,121,117,116,117,120,123,119,121,125,128,126,122,99,119,120,121,117,122,120,125,125,134,135,130,126,122,123,120,124,126,124,114,111,119,120,120,118,119,132,133,128,127,
...much more
...much more
122,120,125,125,134,135,130]}
I'm pretty sure this is the data being used to draw the waveform using canvas.
As far as i understand this process.
SoundCloud creates an image directly after the upload.
You can access it via the tracks endpoint.
SC.get('/tracks/159966669', function(sound) {
$('#result').append('<img src="' +sound.waveform_url+'"/>' );
});
I.e. http://jsfiddle.net/iambnz/fzm4mckd/
Then they use a script like that, written by (former) SoundCloud devs, http://waveformjs.org - which converts the image into floats.
Example call:
http://www.waveformjs.org/w?url=https%3A%2F%2Fw1.sndcdn.com%2FzVjqZOwCm71W_m.png&callback=callback_json1
Example response (extract)
callback_json1([0.07142857142857142,0.5428571428571428,0.7857142857142857,0.65,0.6142857142857143,0.6357142857142857,0.5428571428571428,0.6214285714285714,0.6357142857142857,0.6571428571428571,0.6214285714285714,0.5285714285714286,0.6642857142857143,0.5714285714285714,0.5,0.5,0.6,0.4857142857142857,0.4785714285714286,0.5714285714285714,0.6642857142857143,0.6071428571428571,0.6285714285714286,0.5928571428571429,0.6357142857142857,0.6428571428571429,0.5357142857142857,0.65,0.5857142857142857,0.5285714285714286,0.55,0.6071428571428571,0.65,0.6142857142857143,0.5928571428571429,0.6428571428571429,...[....]
See example here, more detailed on waveform.js
HTML
<div class="example-waveform" id="example2">
<canvas width="550" height="50"></canvas>
</div>
JS
SC.get('/tracks/159966669', function(sound) {
var waveform = new Waveform({
container: document.getElementById("example2"),
innerColor: "#666666"
});
waveform.dataFromSoundCloudTrack(sound);
});
http://jsfiddle.net/iambnz/ro1481ga/
See docs here: http://waveformjs.org/#endpoint
I hope this will help you a bit.
Related
I have an app that is using ngx-bootstrap to show a tooltip on mouseover. I want to test that the content, which is dynamically added, shows properly. In order to do this I have a test that looks like this:
it(shows the right tooltip', fakeAsync(() => {
fixture.debugElement.query(By.directive(TooltipDirective))
.triggerEventHandler('mouseover', null);
tick();
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('.tooltip-inner')).nativeElement)
.toBe('the tooltip text');
}
This results in an error that indicates that fixture.debugElement.query(By.css('.tooltip-inner')): "Cannot read property 'nativeElement' of null"
If I print out the content of fixture.debugElement.nativeElement I get this:
<div id="root1" ng-version="5.2.9">
<my-component>
<div ng-reflect-tooltip="the tooltip text">
<img src="images/test.png">
</div>
<bs-tooltip-container role="tooltip" class="tooltip in tooltip-right">
<div class="tooltip-arrow arrow"></div>
<div class="tooltip-inner">the tooltip text</div>
</bs-tooltip-container>
<my-component>
</div>
The important take away is that the html exists - it is just not accessible by the DebugElement.query.
My current solution to get the spec passing is to change the expect to:
expect(fixture.debugElement.nativeElement.textContent.trim())
.toBe('the tooltip text');
This works, but it is a hack that will fall to pieces if I run into a similar situation with multiple tooltips (for example). Has anyone been able to handle this in a better way? Am I not setting this spec up correctly?
So, I have tried for ages now it seems to track multiple Embedded videos on my test-site with Adobes SiteCatalyst.
Below is the link with documentation I've used
https://gist.github.com/KamalChembath/00106eb266c91777c32e
The problem I've tried to solve is that I want to be able to listen/track already embedded videos, and not actually create the videos using the API and THEN listen to them.
But the documentation "appends" an iframe created by the API into an empty div that needs to have the same id as the iframe id.
But since the embedded video is already there, I don't need this part, obviously.
Please feel free to ask questions if I'm not clear enough.
Anyone had this issue before?
Below is some changes I've made to try to make it append two players into two divs(trying to hack the code I've already got) Putting it all into a for-loop.
Regards everyone!
<div id="player123">
iframe id="player123" type="text/html" width="640" height="390"
src="http://www.youtube.com/embed/-yKNuU8biQo?enablejsapi=1&origin=http://example.com"
frameborder="0"></iframe>
</div>
<div id="player1234">
<iframe id="player1234" type="text/html" width="640" height="390"
src="http://www.youtube.com/embed/VyK-JhjPguY?enablejsapi=1&origin=http://example.com"
frameborder="0"></iframe>
</div>
<script>
var iframeObject = document.getElementsByTagName('iframe');
for ( var i = 0; i < iframeObject.length; i++){
var youtube_id = iframeObject[i].id;
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player(youtube_id, {
videoId: iframeObject[i].src.substring(29, 40),
events: {
'onStateChange': onPlayerStateChange,
'onError' : onPlayerError
}
});
}
</script>
Trying to use equalizer plug, but id doesn't work, and no errors. It`s look like http://goo.gl/OvKy1g. Here is a page http://goo.gl/INMqUL. Do i need include some css for it.
You can use the Foundation Equalize plugin along with Twitter Bootstrap, but you need to do a couple of things to make it work.
DEMO
First, your principle issue is that foundation.js is looking for the corresponding foundation.css. Since you're using Twitter Bootstrap as your base styles, you probably don't want to have to deal with all of the potential style conflicts or having your users download another large css file. Really all that is needed is a reference to the Foundation version and namespace, so just add the following to your css:
meta.foundation-version {
font-family: "/5.4.5/";
}
meta.foundation-data-attribute-namespace {
font-family: false;
}
The second issue is with your markup. You have the data-equalizer-watch attribute applied to the containing .col-sm-4 element, but you have your border on the child element with the class latest-news-item. So change your markup to be:
<div class="row" data-equalizer>
<div class="col-sm-4" >
<div class="latest-news-item" data-equalizer-watch>
<!--Your content here-->
</div>
</div>
<div class="col-sm-4" >
<div class="latest-news-item" data-equalizer-watch>
<!--Your content here-->
</div>
</div>
<div class="col-sm-4" >
<div class="latest-news-item" data-equalizer-watch>
<!--Your content here-->
</div>
</div>
</div>
As you can see in the demo, I was able to get your test page to work with these changes, but I was also able to dramatically reduce the foundation.js file size by using the Custom option on the Foundation Download page and just building a js version with the equalize plugin only. The minified version was 31K. If you're not planning to use any of the other foundation plugins, you might consider using a custom file.
That said, for folks that are looking for an alternative lighter-weight approach, it might be just as easy to write your own jQuery such as by adding a class to the row you want to equalize (I called it 'equalize') and then add:
var row=$('.equalize');
$.each(row, function() {
var maxh=0;
$.each($(this).find('div[class^="col-"]'), function() {
if($(this).height() > maxh)
maxh=$(this).height();
});
$.each($(this).find('div[class^="col-"]'), function() {
$(this).height(maxh);
});
});
Wrap it in a function and you can call it on resize as well if that is important to you.
I'm using this template :
http://getbootstrap.com/examples/offcanvas/
When i put my S3 video player, in big size, it's ok like here :
(source: free.fr)
But if i reduce the size of my page, i've got this:
(source: free.fr)
My line code is :
<div class="jumbotron">
<p><strong>Module 1 :</strong> <a name="un">Introduction</a></p>
<script type="text/javascript">
<!-- Script for video S3 -->
</script>
<p>Description</p>
</div>
How can i keep the width of the div that contain my video with Bootstrap?
Could you also add an example of the javascript you use? You will have to try to set the width of your embedded code to 100%.
I tried some example code from: http://www.icanlocalize.com/site/2010/03/using-amazon-s3-to-host-streaming-videos/:
<script src="http://www.onthegosystems.com/mediaplayer/swfobject.js" type="text/javascript"></script>
<div id="mediaspace">This text will be replaced</div>
<script type="text/javascript">// <![CDATA[
var so = new SWFObject('http://www.onthegosystems.com/mediaplayer/player.swf','mpl','640','467','9');
so.addParam('allowfullscreen','true');
so.addParam('allowscriptaccess','always');
so.addParam('wmode','opaque');
so.addVariable('file','http://d1ftqtsbckf6jv.cloudfront.net/using_glossaries.mp4');
so.write('mediaspace');
// ]]></script>
Al thought the width is hardcoded here, you could also manipulate it with javascript:
$('#mediaspace embed').attr('width','100%');
Also read this part of the docs: http://getbootstrap.com/getting-started/#third-parties. The docs have a Google maps example now but this issue will be happen for all kind of third party content.
For TB2 i used this: How to implement a responsive Youtube embed iframe with Twitter Bootstrap? should work for TB3 too.
I'm using the vLine JavaScript API with the uiVideoPanel widget to make WebRTC video calls.
My code looks like this:
window.vlineClient = client_ =
vline.Client.create({"serviceId": serviceId, "ui": true,
'uiVideoPanel':'showvideo'
});
and HTML:
<div class='span5'
style="width:300px;height:300px;background-color: #eeeeee;"
id='showvideo'>
</div>
However when one person calls another, the video takes up the full screen instead of only 300px by 300px.
How can I control the size of the video?
Make sure you set the CSS position to relative or absolute.
For example, with the HTML you provided it would be:
<div class='span5'
style="width:300px;height:300px;background-color: #eeeeee; position: absolute;"
id='showvideo'>
</div>