Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for video captions #910

Closed
wants to merge 14 commits into from
Closed

Conversation

douzebis
Copy link

@douzebis douzebis commented May 23, 2021

fix #239
(add subtitles for video feature #239)

Generate HTML5 subtitle tracks dynamically based on the contents of the folder
where the video is located.

For example: given a movie 'video.mkv', the player will look for VTT subtitle
files named 'video.XX.vtt' and '.video.XX.vtt', where XX is the two-letter
code for the language.

Signed-off-by: Frederic Ruget [email protected]

Copy link
Contributor

@beardhatcode beardhatcode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, you really reworked this, well done 👍.

Did you try this out on your instance, does it work well?

Converting a string to HTML like this patch suggests at the moment could be dangerous (XSS-attacks). Instead, I suggest you use v-for (see this link for more info)

If you make changes you can just do them here, I will rewrite the git history to tidy things up afterwards 🙂

src/components/Videos.vue Outdated Show resolved Hide resolved
src/components/Videos.vue Outdated Show resolved Hide resolved
src/components/Videos.vue Show resolved Hide resolved
src/components/Videos.vue Outdated Show resolved Hide resolved
@beardhatcode
Copy link
Contributor

beardhatcode commented May 23, 2021

Note to self: Things to check before merging when this is reworked:

  • handles files with emoji's in the name correctly
  • has tests in the video spec and in the naughty files spec
    • I have no idea how to test this, I'm hoping there will be something like videoElement.captions or some value we can query form Plyr
  • check if this works on shared pages

@douzebis
Copy link
Author

There is still a problem with the test Node / node12.x
I don't know what this test does.
Is it possible to run it on my dev setup?

@beardhatcode
Copy link
Contributor

/compile fixup /

@beardhatcode
Copy link
Contributor

That test means that you generated the JS in the wrong way (not with make build-js-production) or something like that (but its not clear from the docs how you should do that, so thats not your fault). I asked a bot to do it now.

@beardhatcode
Copy link
Contributor

image

Cool it works 😄

But if I close the viewer and reopen it again it no longer works.We'll need to sort that out.

@douzebis
Copy link
Author

Its weird.
I can reproduce this (the subtitles do not re-appear when I close and re-open the viewer), but only if the browser's debug window is closed (right-click 'inspect').
When the debug window is open, the subtitles re-appear as expected.

This needs to be investigated...

@douzebis
Copy link
Author

Should be better now.
I believe the root of the problem is that 'tracks' was not properly declared and was not always reactive.

@skjnldsv
Copy link
Member

skjnldsv commented May 25, 2021

Hey!

Thanks for diving into this!

EDIT: I mislooked the PR, I saw a glimpse at some code, but seemed to behave properly, ignore previous comment 😉

@skjnldsv skjnldsv added 3. to review Waiting for reviews enhancement New feature or request labels May 25, 2021
Comment on lines +148 to +332
ko: 'Korean',
kr: 'Kanuri',
ks: 'Kashmiri',
ku: 'Kurdish',
kv: 'Komi',
kw: 'Cornish',
ky: 'Kirghiz',
la: 'Latin',
lb: 'Luxembourgish',
lg: 'Ganda',
li: 'Limburgan',
ln: 'Lingala',
lo: 'Lao',
lt: 'Lithuanian',
lu: 'Luba-Katanga',
lv: 'Latvian',
mg: 'Malagasy',
mh: 'Marshallese',
mi: 'Maori',
mk: 'Macedonian',
ml: 'Malayalam',
mn: 'Mongolian',
mr: 'Marathi',
ms: 'Malay',
mt: 'Maltese',
my: 'Burmese',
na: 'Nauru',
nb: 'Norwegian Bokmål',
nd: 'Ndebele, North',
ne: 'Nepali',
ng: 'Ndonga',
nl: 'Dutch',
nn: 'Norwegian Nynorsk',
no: 'Norwegian',
nr: 'Ndebele, South',
nv: 'Navajo',
ny: 'Nyanja',
oc: 'Occitan',
oj: 'Ojibwa',
om: 'Oromo',
or: 'Oriya',
os: 'Ossetian',
pa: 'Panjabi',
pi: 'Pali',
pl: 'Polish',
ps: 'Pushto',
pt: 'Portuguese',
qu: 'Quechua',
rm: 'Romansh',
rn: 'Rundi',
ro: 'Romanian',
ru: 'Russian',
rw: 'Kinyarwanda',
sa: 'Sanskrit',
sc: 'Sardinian',
sd: 'Sindhi',
se: 'Northern Sami',
sg: 'Sango',
si: 'Sinhala',
sk: 'Slovak',
sl: 'Slovenian',
sm: 'Samoan',
sn: 'Shona',
so: 'Somali',
sq: 'Albanian',
sr: 'Serbian',
ss: 'Swati',
st: 'Sotho',
su: 'Sundanese',
sv: 'Swedish',
sw: 'Swahili',
ta: 'Tamil',
te: 'Telugu',
tg: 'Tajik',
th: 'Thai',
ti: 'Tigrinya',
tk: 'Turkmen',
tl: 'Tagalog',
tn: 'Tswana',
to: 'Tonga',
tr: 'Turkish',
ts: 'Tsonga',
tt: 'Tatar',
tw: 'Twi',
ty: 'Tahitian',
ug: 'Uighur',
uk: 'Ukrainian',
ur: 'Urdu',
uz: 'Uzbek',
ve: 'Venda',
vi: 'Vietnamese',
vo: 'Volapük',
wa: 'Walloon',
wo: 'Wolof',
xh: 'Xhosa',
yi: 'Yiddish',
yo: 'Yoruba',
za: 'Zhuang',
zh: 'Chinese',
zu: 'Zulu',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This most likely already exists, but I can see where maintaining this list could be an issue.
We already maintain such list here: https://github.com/nextcloud/server/blob/9de329a4c2327767d86bd7f594b232eb56af0d01/resources/locales.json

We have a dedicated php method to get those ressources.
I'll suggest we use that instead (you can either have this injected in the page from a InitialState or maybe it's already available
https://github.com/nextcloud/server/blob/9de329a4c2327767d86bd7f594b232eb56af0d01/lib/public/L10N/IFactory.php#L88

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @skjnldsv... so I would like to invoke L10N's php function 'findLanguageFromLocale()' from 'fetchTracks()'.
Please would you provide guidance as to how to import this function into Videos.vue?

public function findLanguageFromLocale(string $app = 'core', string $locale = null)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need the findLanguageFromLocale ?
All of the locale computation should be done on the php side

Comment on lines +334 to +360
const davDir = this.davPath.replace(/[^/]*$/, '')
const videoRoot = this.basename.replace(/[.][^.]+$/, '')
// Create caption tracks for the HTML5 player
// E.g.: <file>.mkv: look for <file>.xx.vtt or .<file>.xx.vtt
const capTracks = []
for (const file of folder) {
const basename = file.basename
const index = basename.indexOf(videoRoot)
// Consider only file... or .file...
if (!(index === 0 || (index === 1 && basename[0] === '.'))) {
continue
}
const suffix = basename.slice(videoRoot.length + index)
// Consider only ...xx.vtt
if (suffix.search(/^[.]..[.]vtt$/) !== 0) {
continue
}
const lang = suffix.slice(1, 3)
const language = languages[lang] || lang
// an array of objects with src, label and lang keys
capTracks.push({
src: davDir + basename,
label: language,
srclang: lang,
})
}
this.tracks = capTracks
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if that should not be better to have all of this in a dedicated php Controller that, given a specific fileName, that would return an array of LANG => filename.

I think the code would benefit from it, especially because the Locale list is managed by a php method.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how to do that (writing a dedicated php Controller).
Please would you point to a similar Controller in NextCloud source, which I could use as a template?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@skjnldsv skjnldsv May 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the controller method should:

  1. Receive the filename as a parameter
  2. Search for existing files with the same filename+langcode using the list of known locale retrieved via the findAvailableLocales of the L10N/IFactory using Dependency Injection
  3. Return an array of langcode => filename so the viewer can use it and build the list accordingly. Should be much faster than our dav endpoint.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I take the challenge :)

By the way, the current proposal does not use the dav endpoint to look for candidate vtt files -- I reckon getFileList() works with the local filesystem?
So we may not see a performance improvement with your proposal.
But in any case the code will be cleaner and easier to maintain.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reckon getFileList() works with the local filesystem?

getFileList is using the dav endpoint.

const response = await client.getDirectoryContents(fixedPath, Object.assign({

src/components/Videos.vue Outdated Show resolved Hide resolved
src/components/Videos.vue Outdated Show resolved Hide resolved
@skjnldsv skjnldsv added 2. developing Work in progress and removed 3. to review Waiting for reviews labels May 25, 2021
@skjnldsv skjnldsv added this to the Nextcloud 22 milestone May 25, 2021
@skjnldsv
Copy link
Member

skjnldsv commented May 25, 2021

Btw, please change your target branch to master, and fix following potential conflicts 😬

@beardhatcode beardhatcode changed the base branch from stable21 to master May 25, 2021 16:36
@beardhatcode beardhatcode changed the base branch from master to stable21 May 25, 2021 16:41
Generate HTML5 subtitle tracks dynamically based on the contents of the folder
where the video is located.

For example: given a movie 'video.mkv', the player will look for VTT subtitle
files named 'video.XX.vtt' and '.video.XX.vtt', where XX is the two-letter
code for the language.

Signed-off-by: Frederic Ruget <[email protected]>
Signed-off-by: Frederic Ruget <[email protected]>
Instead fetchTracks() can be called from options().

Signed-off-by: Frederic Ruget <[email protected]>
douzebis and others added 7 commits May 25, 2021 18:46
Signed-off-by: Frederic Ruget <[email protected]>
Signed-off-by: Frederic Ruget <[email protected]>
Signed-off-by: npmbuildbot-nextcloud[bot] <npmbuildbot-nextcloud[bot]@users.noreply.github.com>
Property track was not properly declared, and sometimes was not
reactive. E.g. closing and re-opening the player would make
subtitles disappear.

Fixing entails declaring tracks in the data() function associated
with the Videos vue.

Signed-off-by: Frederic Ruget <[email protected]>
(Templates are not made to call methods.)

Signed-off-by: Frederic Ruget <[email protected]>
@douzebis
Copy link
Author

Btw, please change your target branch to master, and fix following potential conflicts 😬

OK, I just tested with master. The viewer builds OK.
Unfortunately I'm unable to test with my instance of NextCloud (stable 21):
"The files of the app Viewer (viewer) were not replaced correctly. Make sure it is a version compatible with the server."

I don't know how easy it would be for me to setup an additional instance of NextCloud for testing master... and I don't want to break my production instance :)

@beardhatcode beardhatcode changed the base branch from stable21 to master May 25, 2021 17:06
@beardhatcode
Copy link
Contributor

beardhatcode commented May 25, 2021

@douzebis I rebased your changes on master (you might need to re-clone your repository, or git fetch; git reset origin/stable21)

@beardhatcode
Copy link
Contributor

@douzebis you should just be able to take the built files of master and use them with stable21. Thats no problem (stable21 is practically the same as master). Does that work for you?

@beardhatcode
Copy link
Contributor

One other thing you can do @douzebis is run the program ./cypress/start_server.sh that will start an extra Nextcloud server on your local machine with the curretn version of the viewer app at http://localhost:8082/ (you cna login as user "test" with pass "test", or as "admin" pass "admin" )

@MorrisJobke MorrisJobke mentioned this pull request May 26, 2021
98 tasks
@skjnldsv skjnldsv modified the milestones: Nextcloud 22, Nextcloud 23 May 26, 2021
@douzebis
Copy link
Author

Well I could not find time to work on the requested changes but I still managed to do a big mess by triggering github's 'fetch upstream' button... and updating my forked version of 'stable21' to 'master' :( :(

The last big 'push' is my attempt at reverting to previous stable21 state.

Please advise, I can re-fork from scratch and redo the modifications to src/components/Videos.vue, so that you no longer have to deal with this mess...

@douzebis
Copy link
Author

@douzebis you should just be able to take the built files of master and use them with stable21. Thats no problem (stable21 is practically the same as master). Does that work for you?

Nope, unfortunately it does not work.
When navigating to the welcome portal (https://nextcloud.domain), nextcloud complains about:
"The files of the app Viewer (viewer) were not replaced correctly. Make sure it is a version compatible with the server."

This may have to do with the components version numbers in 'master' not being compatible with those in 'stable21'?

@beardhatcode
Copy link
Contributor

@douzebis don't worry about it, just continue your work here, I'll rebase your changes when everything is done

@beardhatcode beardhatcode changed the base branch from master to stable21 May 27, 2021 20:36
@beardhatcode beardhatcode changed the base branch from stable21 to master May 27, 2021 20:36
@beardhatcode
Copy link
Contributor

Alternatively, @douzebis , I can put this branch back on stable21 for you, just let me know.

@skjnldsv
Copy link
Member

#915

@skjnldsv skjnldsv closed this May 28, 2021
@skjnldsv
Copy link
Member

Moved and rebased to new branch here, will be much easier.
You can edit and continue your work there 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2. developing Work in progress enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add subtitles for video feature Support for subtitles in the video player
3 participants