I added another quality for showing the video, but there is no choice of another quality in the video player
jwplayer("player2").setup({
image: "https://cdn.jwplayer.com/v2/media/tkM1zvBq/poster.jpg?width=720",
"type": "video/mp4",
"sources": [{
"file": "http://*:1935/vod/volikogu_1080p.mp4/playlist.m3u8",
"label": "1080p"
}, {
"file": "http://*:1935/vod/volikogu_720p.mp4/playlist.m3u8",
"label": "720p"
}, {
"file": "http://*:1935/vod/volikogu_360p.mp4/playlist.m3u8",
"label": "360p"
}],
"label": "H.264 320px"
});
I'm seeing a few things in the above config that could be causing poor behavior in the player. First off, you have type on the top level when it should be on the same level as your source objects in the sources array. It also appears as though type is hls and not video/mp4 (based on the m3u8 extension).
Does the following setup change any behavior for you?
jwplayer("player2").setup({
image: "https://cdn.jwplayer.com/v2/media/tkM1zvBq/poster.jpg?width=720"
"sources": [{
"file": "http://*:1935/vod/volikogu_1080p.mp4/playlist.m3u8",
"label": "1080p",
"type": "hls"
}, {
"file": "http://*:1935/vod/volikogu_720p.mp4/playlist.m3u8",
"label": "720p",
"type": "hls"
}, {
"file": "http://*:1935/vod/volikogu_360p.mp4/playlist.m3u8",
"label": "360p",
"type": "hls"
}]
});
If the type of your files is mp4 then replace "type": "hls" with "type": "mp4" in the above.
You would be best served to have all of your child manifests in one single parent manifest. Do not put multiple m3u8's as different sources. Let the player or the browser change the quality based on a single master manifest. Also, your "label" and "type" attributes are not valid, I would remove them entirely.
Related
I'm running a simple custom Google Chrome startpage consisting of a background .gif and a google searchbar. However, Google Chrome interprets it as something other than the default startpage, and thus won't show the native bookmark bar, unless the option to show it everywhere is checked (which is awkard for my monitor resolution).
The Google Chrome bookmarks file is located at C:\Users\UserName\AppData\Local\Google\Chrome\User Data\Default\bookmarks,below I'll paste a sample of its structure.
Just looking at this, do you think there's a way to either show the native bookmark ONLY in my custom startpage, or to fetch the information in that bookmarks file and display it on my own?
{
"checksum": "REDACTED",
"roots": {
"bookmark_bar": {
"children": [ {
"children": [ {
"date_added": "13222412798372622",
"date_last_used": "0",
"guid": "REDACTED",
"id": "7",
"name": "Whatsapp",
"type": "url",
"url": "https://web.whatsapp.com/"
}, {
"date_added": "13126908348807315",
"date_last_used": "13317078268398707",
"guid": "REDACTED",
"id": "8",
"meta_info": {
"last_visited_desktop": "REDACTED"
},
"name": "YouTube",
"type": "url",
"url": "https://www.youtube.com/feed/subscriptions"
}, {
"date_added": "13126908407318057",
"date_last_used": "13317078266263899",
"guid": "REDACTED",
"id": "9",
"meta_info": {
"last_visited_desktop": "REDACTED"
},
I am using timeline.js. i am new to timeline.js. I want to add the image in flag which is shown on timeline with different image icons for different points. I didn't get any solution for this in documentation or anything. Image of where i want to add image is shown in the image attached. flag_image
Please find the demo in following link. Codepen
var dataObject = {
"timeline": {
"headline": "Welcome to TimelineJS",
"startDate": "2011,12,10",
"type": "default",
"text": "<p>TimelineJS is an open-source tool that enables you to build visually-rich interactive timelines and is available in 40 languages.</p><p>You're looking at an example of one right now.</p><p>Click on the arrow to the right to learn more.</p>",
"asset": {
"media": "https://2.bp.blogspot.com/-dxJbW0CG8Zs/TmkoMA5-cPI/AAAAAAAAAqw/fQpsz9GpFdo/s1600/voyage-dans-la-lune-1902-02-g.jpg",
"credit": "",
"caption": ""
},
"date": [{
"startDate": "2011,12,10",
"headline": "Exception initiated by XYZ",
"asset": {
"media": "/static/welcome/step3.png",
"credit": "",
"caption": "Screenshot from TimelineJS Embed Generator tool (see below)"
}
}, {
"startDate": "2012,12,10",
"headline": "Exception initiated by XYZ",
"asset": {
"media": "/static/welcome/step3.png",
"credit": "",
"caption": "Screenshot from TimelineJS Embed Generator tool (see below)"
}
}, {
"startDate": "2011,12,11",
"headline": "Tech review approved by ABC",
"text": "Timeline can automatically pull in photos, videos from YouTube or Vimeo, tweets, wikipedia entries, and many other media types to help tell your story.",
"asset": {
"media": "",
"credit": "",
"caption": "Screenshot from TimelineJS Embed Generator tool (see below)"
}
}, {
"startDate": "2011,12,12",
"headline": "Approved by all",
"text": "Timeline can automatically pull in photos, videos from YouTube or Vimeo, tweets, wikipedia entries, and many other media types to help tell your story.",
"asset": {
"media": "",
"credit": "",
"caption": "Screenshot from TimelineJS Embed Generator tool (see below)"
}
}, {
"startDate": "2011,12,13",
"headline": "Closure requested",
"text": "Timeline can automatically pull in photos, videos from YouTube or Vimeo, tweets, wikipedia entries, and many other media types to help tell your story.",
"asset": {
"media": "https://image.ibb.co/eMGfya/episodic_failed.png",
"credit": "",
"caption": "Screenshot from TimelineJS Embed Generator tool (see below)"
}
}],
"era": [{
"startDate": "2011,12,10",
"endDate": "2011,12,11",
"headline": "Revision1",
"tag": "This is Optional"
}, {
"startDate": "2011,12,13",
"endDate": "2011,12,14",
"headline": "Revision2",
"tag": "This is Optional"
}
]
}
}
createStoryJS({
type: 'timeline',
width: '800',
height: '600',
source: dataObject,
embed_id: 'my-timeline',
hash_bookmark: true
});
.classRed
{
background-color:red;
}
/* .vco-slider .slider-container-mask {
display: none;
} */
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdn.knightlab.com/libs/timeline/latest/js/storyjs-embed.js"></script>
<link href="https://cdn.knightlab.com/libs/timeline/latest/css/timeline.css" rel="stylesheet"/>
<div id="my-timeline"></div>
You would need to add the image into the div element that represents the flag.
An easy way to do this is to use the browser Dev tools on an open timeline, use the element click tool to select a flag, determine the class used by flags (as well as a set of classes that makes a unique path is CSS class names to a flag) and use jquery/javascript to position an image element inside the the identified div element (that is, the flag).
In terms of using an image for each flag based on the type of event (of the flag), you will likely need to use text from your event to identify it in a div (like in the .each method of jquery after you apply the selector).
I am suggesting this as I changed the color of the flag based on types of event I had defined, and used the event type in the title field, parsed that text for the event name (the type was added as first word, so I parsed the string from position 0) and then changed the background-color CSS attribute (with !important).
BTW, I took this approach so as to not change the source code (post-processing the DOM).
Hope this helps some
The guys from guide4you did a great job making this lib opensource!!
I've succeeded in having a working demo guide4you sample.
How adjustable is the lib?
For instance how can I add layers with GeoJSON instead of KML.
Can the layers be added dynamically (with own javascript) instead of predefined?
Take this as example: https://openlayers.org/en/latest/examples/geojson.html
To be more specific: how can that example work together with guide4you ?
Kind regards,
Sam
To use a GeoJSON layer in guide4you you can just specify the type "GeoJSON" in the layerconfig.
{
"id": "3",
"type": "GeoJSON",
"source": {
"url": "path/to/geojson"
}
}
See also https://github.com/KlausBenndorf/guide4you/blob/master/conf/full/layers.commented.json for some examples
If you like to add a layer on the fly with javascript you can use this api function:
map.get('api').addFeatureLayer({
"id": "3",
"type": "GeoJSON",
"source": {
"url": "path/to/geojson"
},
"visible": true
})
the possible options are the same as in the layer config.
If you like to add only new features you can create a layer with type "Intern" and add the features with openlayers functionalities. The source of a feature layer is a subclass of ol.source.Vector.
In the example below I am assuming that geojsonObject is of the same kind as in the geojson example of openlayers.
var layer = map.get('api').addFeatureLayer({
"id": "3",
"type": "Intern",
"source": {
"features": []
},
"visible": true
});
layer.getSource().addFeatures((new ol.format.GeoJSON()).readFeatures(geojsonObject));
And last but not least you can use a simplified api to define features inside a layerConfig object like this:
{
"id": "3",
"type": "Intern",
"source": {
"features": [{
"id": 6,
"name": "Some feature",
"description: "Some description",
"style": "#defaultStyle",
"geometryWKT": "... any wkt string here ..."
},{
"geometryWKT": "... any wkt string here ..."
}]
}
}
this can be used either in a layerConfig file or in the addFeatureLayer api method.
I'm using Contentful and have a content model which uses a series of related fields. I am querying my content in NodeJS using the JS api. If I call get entries, like so
contentfulClient.getEntries({
content_type: 'homePage'
})
it fetches all the content of type homePage, and includes the actual field data for each related field, like so
"subField": {
"sys": {
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "#######"
}
},
"id": "#######",
"type": "Entry",
"createdAt": "2017-03-10T15:58:25.697Z",
"updatedAt": "2017-03-10T15:58:25.697Z",
"revision": 1,
"contentType": {
"sys": {
"type": "Link",
"linkType": "ContentType",
"id": "homeSubField"
}
},
"locale": "en-GB"
},
"fields": {
"category": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "#######"
}
},
"subFieldContent": "Some field content"
}
},
However, if I call a specific entry with an ID, like
contentfulClient.getEntry('1234567890')
Then each linked field is just returned as a reference with an ID, like
"subField": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "#######"
}
},
How can I get the full text when calling getEntry, like I do with getEntries?
Unfortunately Contentful does not include referenced content when fetching a content item by id directly. One way around this is to instead use the getEntries method, but filter by sys.id. That way you'll get the same entry back, although in an array, but it will also include referenced content.
contentfulClient.getEntries({
content_type: 'homePage',
sys.id: '1234567890'
})
This also results in a single request instead of multiple as you would end up with when using the GetEntry method and then resolving each referenced content item manually.
I have a Strongloop Loopback Node.js project with some models and relations.
The problem at hand
My problem relates how to query only those Media instances that have a relation to a certain Tag id, using the Angular SDK - while not querying Tags.media (which return Tag instances), but instead making a query somehow that returns plain Media instances.
Please read below for specific information..
Spec
Basically, I have a Model Media which has many 'tags' (model Tag). Think of a image file (Media) having various EXIF tags (Tag). Here is the relation spec (this all works as expected):
Media (media.json):
{
"name": "media",
"base": "PersistedModel",
"properties": {
"id": {
"type": "string",
"id": true
}
},
"relations": {
"tags": {
"type": "hasAndBelongsToMany",
"model": "tag"
}
}
Tag (tag.json):
{
"name": "tag",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string",
"required": true
}
},
"relations": {
"medias": {
"type": "hasAndBelongsToMany",
"model": "media"
}
},
"acls": [],
"methods": []
}
Solutions
Now, I know I could do a query like this (using Angular SDK in my example, but the syntax is the same):
injector.get('Tag').find({
'filter': {
'include': 'medias',
'where': {'id': <mytagid>}
}
});
My problem with this approach is, that I receive 1 (one) Tag instance with attached Media instances. This disrupts why whole workflow as I deal only with Media instances.. i just want to filter by Tag id, not bother about Tag at all.
Bottom line
If I see the API explorer (/explorer/), the return value of GET /api/tags/<myTagID>/medias is exactly what I need - an array of Media objects - but how to query them exactly like this using the Angular SDK (lb_services)?
I had a similar problem. One recommendation is to open the lb-services.js and try to find: /tags/:id/medias or something similar. Then you will find a comment like this: // INTERNAL. Use Tags.medias() instead. Or something similar. So that is the method that you should call. Do not call the "prototype$__get....." methods.
Then just call what it says there I suppose: Tag.medias({id:})
Other suggestions:
As you said in your description Media has many Tags. So why not use just
{
"name": "media",
"base": "PersistedModel",
"properties": {
"id": {
"type": "string",
"id": true
}
},
"relations": {
"tags": {
"type": "hasMany", <---------- hasMany
"model": "tag",
"foreignKey": "tagId" <---FK name
}
}
and
for the tags just belongsTo as type.
{
"name": "tag",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string",
"required": true
}
},
"relations": {
"medias": {
"type": "belongsTo",
"model": "media",
"foreignKey": "mediaId" <---FK name
}
},
"acls": [],
"methods": []
}
But really I don't think this is the problem because you said when you request GET /api/tags/<myTagID>/medias it returns what you want.
Then, in AngularJS you can use:
Media.tags({id:<mediaId>})
for media/:id/tags
and for the other side try:
Tag.medias({id:<tagId>})
Tag.find({
filter:{
where:{mediaId: <mediaId>} <----mediaId comes from FK name
}
})
In this case both are persistent models there is no problems, I had permission problems when doing a similar thing with data that extends User type. But that is another story...
Hope this is helpful, I changed some stuff from a similar app that I am doing and hope not making so many errors when adapting to your code...