Skip to content

Commit 3fac107

Browse files
Fix missing Poster functionality and Autoplay for cld-video (#141)
1 parent d285303 commit 3fac107

File tree

9 files changed

+158
-66
lines changed

9 files changed

+158
-66
lines changed

dist/Cloudinary.common.js

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19678,6 +19678,10 @@ var setup_setup = {
1967819678
}
1967919679
},
1968019680
methods: {
19681+
/**
19682+
* Set up the Cloudinary instance, allowing it later to be used to create URLs
19683+
* @param extraConfigs
19684+
*/
1968119685
setup: function setup(extraConfigs) {
1968219686
if (!this.cloudinary) {
1968319687
this.cloudinary = new cloudinary_core["Cloudinary"](this.toSnakeCase(this.defaultConfigurations));
@@ -20729,35 +20733,60 @@ var defaultSourceTypes = cloudinary_core["Cloudinary"].DEFAULT_VIDEO_SOURCE_TYPE
2072920733
return sources;
2073020734
},
2073120735
getPosterUrl: function getPosterUrl() {
20732-
var _this$poster;
20736+
// Automatic poster, when no specific poster properties are passed.
20737+
if (!this.poster) {
20738+
// Take the video URL and render it as an image, applying all child transformations
20739+
// In a case like this: <cld-video width="100"/> the width config is already populated in the Cloudinary object
20740+
// All we need to do is apply the child/chained transformations
20741+
return this.cloudinary.url(this.publicId, this.toSnakeCase({
20742+
transformation: this.extraTransformations || [],
20743+
format: 'jpg',
20744+
// The video publicId is a video, we need to change it to jpg for the poster
20745+
resourceType: 'video' // the default resourceType is image, we need to ensure video is used.
20746+
20747+
}));
20748+
} // If poster is directly a string, we just return it
20749+
// <cld-video poster="my/path/to/poster.jpg"/>
20750+
20751+
20752+
if (typeof this.poster === 'string') {
20753+
return this.poster;
20754+
} // If poster is used as a child component
20755+
// <cld-video> <cld-poster publicId="sample" /></>cld-video>
20756+
// This is treated like a regular transformation
20757+
// All poster properties are used to calculate the transformation
20758+
// We ignore child transformations, and only use what was explciitly provided.
20759+
2073320760

20734-
var isPosterAnUrl = typeof this.poster === 'string';
20735-
if (isPosterAnUrl) return this.poster;
20736-
var hasInlinePosterOptions = this.poster && !isPosterAnUrl;
20737-
var options = hasInlinePosterOptions ? this.poster : {};
20738-
return this.cloudinary.url(((_this$poster = this.poster) === null || _this$poster === void 0 ? void 0 : _this$poster.publicId) || this.publicId, this.toSnakeCase(options));
20761+
if (this.poster && this.poster.publicId) {
20762+
// const cldURLOptions = hasInlinePosterOptions ? this.poster : this.extraTransformations
20763+
return this.cloudinary.url(this.poster.publicId, this.toSnakeCase(this.poster));
20764+
} // In all other cases, return an empty string
20765+
20766+
20767+
return '';
2073920768
}
2074020769
},
2074120770
mounted: function mounted() {
2074220771
this.$videoElement = this.$refs.videoElement;
2074320772
},
20773+
created: function created() {
20774+
this.setup(this.$attrs);
20775+
},
2074420776
render: function render(h) {
2074520777
if (!this.publicId) return null;
2074620778
var children = this.$slots.default || [];
2074720779
var cldPoster = getCldPoster(children);
20748-
var hasExtraTransformations = children.length > 1 || children.length === 1 && !cldPoster;
20749-
/* Render the children first to get the extra transformations (if there is any) */
20750-
20751-
if (hasExtraTransformations && !this.extraTransformations.length) {
20752-
return h("div", {
20753-
attrs: this.attrs
20754-
}, this.$slots.default);
20755-
}
20756-
20757-
this.setup(this.$attrs);
2075820780
var sources = this.getSources();
2075920781
var poster = cldPoster ? this.posterUrl : this.getPosterUrl();
20760-
return h("video", helper_default()([{}, {
20782+
return h("video", helper_default()([{
20783+
"attrs": {
20784+
"autoplay": this.$attrs.autoplay
20785+
},
20786+
"domProps": {
20787+
"muted": this.$attrs.muted
20788+
}
20789+
}, {
2076120790
"attrs": this.$attrs
2076220791
}, {
2076320792
"attrs": {

dist/Cloudinary.common.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/Cloudinary.umd.js

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19687,6 +19687,10 @@ var setup_setup = {
1968719687
}
1968819688
},
1968919689
methods: {
19690+
/**
19691+
* Set up the Cloudinary instance, allowing it later to be used to create URLs
19692+
* @param extraConfigs
19693+
*/
1969019694
setup: function setup(extraConfigs) {
1969119695
if (!this.cloudinary) {
1969219696
this.cloudinary = new cloudinary_core["Cloudinary"](this.toSnakeCase(this.defaultConfigurations));
@@ -20738,35 +20742,60 @@ var defaultSourceTypes = cloudinary_core["Cloudinary"].DEFAULT_VIDEO_SOURCE_TYPE
2073820742
return sources;
2073920743
},
2074020744
getPosterUrl: function getPosterUrl() {
20741-
var _this$poster;
20745+
// Automatic poster, when no specific poster properties are passed.
20746+
if (!this.poster) {
20747+
// Take the video URL and render it as an image, applying all child transformations
20748+
// In a case like this: <cld-video width="100"/> the width config is already populated in the Cloudinary object
20749+
// All we need to do is apply the child/chained transformations
20750+
return this.cloudinary.url(this.publicId, this.toSnakeCase({
20751+
transformation: this.extraTransformations || [],
20752+
format: 'jpg',
20753+
// The video publicId is a video, we need to change it to jpg for the poster
20754+
resourceType: 'video' // the default resourceType is image, we need to ensure video is used.
20755+
20756+
}));
20757+
} // If poster is directly a string, we just return it
20758+
// <cld-video poster="my/path/to/poster.jpg"/>
20759+
20760+
20761+
if (typeof this.poster === 'string') {
20762+
return this.poster;
20763+
} // If poster is used as a child component
20764+
// <cld-video> <cld-poster publicId="sample" /></>cld-video>
20765+
// This is treated like a regular transformation
20766+
// All poster properties are used to calculate the transformation
20767+
// We ignore child transformations, and only use what was explciitly provided.
20768+
2074220769

20743-
var isPosterAnUrl = typeof this.poster === 'string';
20744-
if (isPosterAnUrl) return this.poster;
20745-
var hasInlinePosterOptions = this.poster && !isPosterAnUrl;
20746-
var options = hasInlinePosterOptions ? this.poster : {};
20747-
return this.cloudinary.url(((_this$poster = this.poster) === null || _this$poster === void 0 ? void 0 : _this$poster.publicId) || this.publicId, this.toSnakeCase(options));
20770+
if (this.poster && this.poster.publicId) {
20771+
// const cldURLOptions = hasInlinePosterOptions ? this.poster : this.extraTransformations
20772+
return this.cloudinary.url(this.poster.publicId, this.toSnakeCase(this.poster));
20773+
} // In all other cases, return an empty string
20774+
20775+
20776+
return '';
2074820777
}
2074920778
},
2075020779
mounted: function mounted() {
2075120780
this.$videoElement = this.$refs.videoElement;
2075220781
},
20782+
created: function created() {
20783+
this.setup(this.$attrs);
20784+
},
2075320785
render: function render(h) {
2075420786
if (!this.publicId) return null;
2075520787
var children = this.$slots.default || [];
2075620788
var cldPoster = getCldPoster(children);
20757-
var hasExtraTransformations = children.length > 1 || children.length === 1 && !cldPoster;
20758-
/* Render the children first to get the extra transformations (if there is any) */
20759-
20760-
if (hasExtraTransformations && !this.extraTransformations.length) {
20761-
return h("div", {
20762-
attrs: this.attrs
20763-
}, this.$slots.default);
20764-
}
20765-
20766-
this.setup(this.$attrs);
2076720789
var sources = this.getSources();
2076820790
var poster = cldPoster ? this.posterUrl : this.getPosterUrl();
20769-
return h("video", helper_default()([{}, {
20791+
return h("video", helper_default()([{
20792+
"attrs": {
20793+
"autoplay": this.$attrs.autoplay
20794+
},
20795+
"domProps": {
20796+
"muted": this.$attrs.muted
20797+
}
20798+
}, {
2077020799
"attrs": this.$attrs
2077120800
}, {
2077220801
"attrs": {

dist/Cloudinary.umd.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/Cloudinary.umd.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/Cloudinary.umd.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/CldVideo/CldVideo.vue

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,44 +93,54 @@ export default {
9393
return sources
9494
},
9595
getPosterUrl() {
96-
const isPosterAnUrl = (typeof this.poster) === 'string'
97-
if (isPosterAnUrl) return this.poster
96+
// Automatic poster, when no specific poster properties are passed.
97+
if (!this.poster) {
98+
// Take the video URL and render it as an image, applying all child transformations
99+
// In a case like this: <cld-video width="100"/> the width config is already populated in the Cloudinary object
100+
// All we need to do is apply the child/chained transformations
101+
return this.cloudinary.url(this.publicId, this.toSnakeCase({
102+
transformation: this.extraTransformations || [],
103+
format: 'jpg', // The video publicId is a video, we need to change it to jpg for the poster
104+
resourceType: 'video' // the default resourceType is image, we need to ensure video is used.
105+
}))
106+
}
107+
108+
// If poster is directly a string, we just return it
109+
// <cld-video poster="my/path/to/poster.jpg"/>
110+
if (typeof this.poster === 'string') {
111+
return this.poster
112+
}
98113
99-
const hasInlinePosterOptions = this.poster && !isPosterAnUrl
100-
const options = hasInlinePosterOptions ? this.poster : {}
114+
// If poster is used as a child component
115+
// <cld-video> <cld-poster publicId="sample" /></>cld-video>
116+
// This is treated like a regular transformation
117+
// All poster properties are used to calculate the transformation
118+
// We ignore child transformations, and only use what was explciitly provided.
119+
if (this.poster && this.poster.publicId) {
120+
// const cldURLOptions = hasInlinePosterOptions ? this.poster : this.extraTransformations
121+
return this.cloudinary.url(this.poster.publicId, this.toSnakeCase(this.poster))
122+
}
101123
102-
return this.cloudinary.url(this.poster?.publicId || this.publicId, this.toSnakeCase(options))
124+
// In all other cases, return an empty string
125+
return '';
103126
}
104127
},
105128
mounted() {
106129
this.$videoElement = this.$refs.videoElement;
107130
},
131+
created() {
132+
this.setup(this.$attrs);
133+
},
108134
render(h) {
109135
if (!this.publicId) return null
110136
111137
const children = this.$slots.default || []
112-
113-
const cldPoster = getCldPoster(children)
114-
const hasExtraTransformations = children.length > 1 || (children.length === 1 && !cldPoster)
115-
116-
/* Render the children first to get the extra transformations (if there is any) */
117-
if (hasExtraTransformations && !this.extraTransformations.length) {
118-
return h(
119-
"div", {
120-
attrs: this.attrs
121-
},
122-
this.$slots.default
123-
)
124-
}
125-
126-
this.setup(this.$attrs)
127-
128-
const sources = this.getSources()
129-
130-
const poster = cldPoster ? this.posterUrl : this.getPosterUrl()
138+
const cldPoster = getCldPoster(children);
139+
const sources = this.getSources();
140+
const poster = cldPoster ? this.posterUrl : this.getPosterUrl();
131141
132142
return (
133-
<video attrs={this.$attrs} poster={poster} ref="videoElement">
143+
<video autoplay={this.$attrs.autoplay} muted={this.$attrs.muted} attrs={this.$attrs} poster={poster} ref="videoElement">
134144
{ sources.map((source, index) => <source key={index} attrs={source} />)}
135145
{ this.$slots.default }
136146
</video>

src/mixins/setup.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ export const setup = {
1717
},
1818
},
1919
methods: {
20-
setup(extraConfigs) {
20+
/**
21+
* Set up the Cloudinary instance, allowing it later to be used to create URLs
22+
* @param extraConfigs
23+
*/
24+
setup(extraConfigs) {
2125
if (!this.cloudinary) {
2226
this.cloudinary = new Cloudinary(this.toSnakeCase(this.defaultConfigurations))
2327
}
@@ -32,4 +36,4 @@ export const setup = {
3236
return Util.withSnakeCaseKeys(options)
3337
}
3438
}
35-
};
39+
};

tests/unit/Video/poster.spec.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ import CldPoster from "../../../src/components/CldVideo/CldPoster";
55
import CldTransformation from "../../../src/components/CldTransformation/CldTransformation";
66

77
describe("CldVideo Component tests", () => {
8+
it("should render a video poster as a video/upload type", async () => {
9+
const wrapper = mount({
10+
template: `
11+
<cld-video width="100" crop="fill" cloudName="demo" class="video" ref="videoElement" public-id="sample">
12+
<cld-transformation effect="sepia" />
13+
</cld-video>
14+
`,
15+
}, {
16+
components: { CldVideo, CldTransformation }
17+
});
18+
19+
await Vue.nextTick();
20+
21+
const video = wrapper.find('video');
22+
23+
expect(video.attributes("poster")).toEqual(
24+
'http://res.cloudinary.com/demo/video/upload/e_sepia/c_fill,w_100/sample.jpg'
25+
);
26+
});
27+
828
it("should render a video poster", async () => {
929
const wrapper = mount({
1030
template: `
@@ -91,7 +111,7 @@ describe("CldVideo Component tests", () => {
91111
const video = wrapper.find('video');
92112

93113
expect(video.attributes("poster")).toBe(
94-
"http://res.cloudinary.com/demo/image/upload/face_top"
114+
"http://res.cloudinary.com/demo/video/upload/face_top.jpg"
95115
);
96116
});
97117

0 commit comments

Comments
 (0)