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

Asynchronous music-metadata updates while streaming #1449

Merged
merged 24 commits into from
Sep 26, 2018
Merged

Asynchronous music-metadata updates while streaming #1449

merged 24 commits into from
Sep 26, 2018

Conversation

Borewit
Copy link
Member

@Borewit Borewit commented Aug 13, 2018

Implementation of asynchronous tag update events (send each time music-metadata founds a new generic tag or format change while it is parsing the downloaded stream build up from the torrent chunks).

Solution for #1340: Improve the music metadata reading and updating mechanism

bnjmnt4n and others added 2 commits October 6, 2016 19:42
…ating.

Previously, they were only installed when the preference was changed.
This caused the handlers to point to non-existing files after updates
occurred and older versions were removed by Squirrel.

Closes #791, #911.
@Borewit
Copy link
Member Author

Borewit commented Aug 13, 2018

@codealchemist Can you please review these changes?

Note that the dependency of music-metadata is not updated yet.
Since it a fairly large change to music-metadata, I would like have it reviewed prior to merging it.

At this time you need to checkout feature/async-updates branch of music-metadata, which is still a pending pull request.

You can yarn to link to your local music-metadata branch.

@Borewit Borewit changed the title webtorrent/webtorrent-desktop#1340: Switch to async metadata updates. Asynchronous music-metadata updates while streaming Aug 13, 2018
@Borewit
Copy link
Member Author

Borewit commented Aug 13, 2018

Partial music-metadata update:
async-update 01

Few seconds later:
async-update 02

@codealchemist
Copy link
Contributor

Oh, I can't play any files on first try.
But it doesn't throw any errors; strange.
Tomorrow I'll try again fresh, I'm too sleepy now.

Just wanted to say this is awesome stuff!
And I'm looking forward to testing it.
:)

@codealchemist
Copy link
Contributor

BTW, I installed music-metadata from your branch like this:
npm i Borewit/music-metadata#feature/async-updates

@Borewit
Copy link
Member Author

Borewit commented Aug 15, 2018

@codealchemist:

I am looking forward to your feedback!

npm i Borewit/music-metadata#feature/async-updates

I guess that is not working, because the TypeScript in music-metadata is not getting compiled.

I use yarn, to link the local checked out dependency.

git clone https://github.com/Borewit/music-metadata.git
cd music-metadata
git checkout feature/async-updates
yarn install
yarn build
yarn link
cd ../webtorrent-desktop
yarn link music-metadata

@Borewit
Copy link
Member Author

Borewit commented Aug 15, 2018

This is the test set I am currently using: Audio torrent test set v01.zip

The MPEG-4 Audio Book File in 'Glories of Ireland 1801 librivox (audio book).torrent', are not working yet. That is why I started:

  1. Reuse media extensions #1450: adding the .m4b extension, which I thought I had done before...
  2. Failed to parse MPEG-4 Audio Book File (m4b) Borewit/music-metadata#127 which is marked as bug, but it is in fact a workaround for an ugly tag appearing in these m4b file.

As a reminder for an entry on the change-log and to ensure it got tested I created: #1452

Something else I noticed: suspiciously frequently, the track number is not visualized.
Update: issue confirmed, created fix: #1454

Copy link
Contributor

@codealchemist codealchemist left a comment

Choose a reason for hiding this comment

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

I tested with mp3 and ogg and it's working, yay!
I saw 13 async calls which initially looked like too many, but we might not be using all the data we get.
Didn't have time to check that yet.

Great work @Borewit !

skipCovers: true,
fileSize: file.length,
observer: event => {
console.log(`async-audio-metadata-update: file='${file.name}', type=${event.tag.type}, tag-id=${event.tag.id}`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can remove this extra logging before merging.
:)

@@ -216,9 +216,7 @@ function renderAudioMetadata (state) {
const elems = []

// Audio metadata: artist(s)
const artist = common.albumartist || common.artist ||
(common.artists && common.artists.filter(function (a) { return a }).join(', ')) ||
Copy link
Contributor

Choose a reason for hiding this comment

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

common.artists array is not available anymore?

Copy link
Member Author

Choose a reason for hiding this comment

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

It is still available, but common.artist is already designed to summarize the artist(s) in a single string.
Either derived from common.artists or directly from the metadata.

In other words, the code removed is already done in music-metadata.

@Borewit
Copy link
Member Author

Borewit commented Aug 16, 2018

I saw 13 async calls which initially looked like too many, but we might not be using all the data we get.

There maybe indeed calls now which do not effect any visual change because the metadata triggering the call is not used. I thought about this, and assumed these callback were not to expensive. But the source of all evil in the world are assumptions ;-). To keep things simple I decided not to filter the events, but that can be done if you think it is worth it.

@codealchemist
Copy link
Contributor

About having extra async calls I think it's ok.
If we want to do further optimizations in the future maybe we can tell music-metadata the fields we're interested about to only do the callback for those.
This is really good already!

Copy link
Contributor

@codealchemist codealchemist left a comment

Choose a reason for hiding this comment

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

Looking good!
Thanks!

@codealchemist
Copy link
Contributor

Sample OGG file properly getting async metadata:
image

@Borewit
Copy link
Member Author

Borewit commented Aug 17, 2018

@codealchemist Thanks for reviewing, I think this one made a good difference.

I just found out that there are some cases where events are not triggered yet. Which may not be even noticeable for the end user, Fixed.

If we want to do further optimizations in the future maybe we can tell music-metadata the fields we're interested about to only do the callback for those.

I am not so sure about putting the filter in music-metadata. I don't think that is any better then just do something with the event which we are interested in. Callbacks are generated in music-metadata, with or without one listening in the app, because conversion and merging has to take place to maintain the common model. I would go for switch (sorry @feross, I know you hate them ;-) on the event.tag properties. Maybe it is more beneficial to wire more detailed screen updates with corresponding event updates. I have hardly any experience with React btw.

// Config is now on the new version
state.saved.version = config.APP_VERSION
}

// Whenever the app is updated, re-install default handlers if the user has
// enabled them.
function installHandlers (saved) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this enhancement is worth its own PR.
But if the other folks agree we can add it here.
Really nice catch BTW :)

@Borewit Borewit requested a review from mathiasvr September 26, 2018 05:36
@Borewit
Copy link
Member Author

Borewit commented Sep 26, 2018

@mathiasvr this one should be good for merging as well.

@mathiasvr
Copy link
Contributor

Maybe it is not relevant to this PR, but doesn't the metadata streaming force webtorrent to download the file sequentially, even if the user wants to seek to a position later in the file?

Anyway, I think we can merge this and consider potential optimizations later.

A couple of things:

@Borewit
Copy link
Member Author

Borewit commented Sep 26, 2018

Maybe it is not relevant to this PR, but doesn't the metadata streaming force webtorrent to download the file sequentially, even if the user wants to seek to a position later in the file?

Not sure if the metadata is also driving the sequential download. But if metadata doesn't trigger it, the audio player will do for sure will, despite the fact that you want to start playing half way for multiple reasons:

  1. The header information is stored at the beginning of the file.
  2. The audio player will read the metadata chunks as well
  3. The Node stream does not provide a mechanism to jump in the stream

Although it is depending on the file format and provided settings, music-metadata doesn't read necessary to the end of the stream, in many cases, a relative small portion of the beginning of the stream is sufficient.

I have the impression the sequential download is already prioritized at the moment you navigate to the audio track "page".

For sure this PR doesn't change the way the audio metadata is read, that's the same is as before. It starts to display metadata during parsing.

But if you see a way how we can do things smarter, I will look into it.

Could you remove the commit from #997, I think it should be handled separately.

Regarding that commit, for sure I did not inject that on purpose.
I checked my local branch and I cannot find that commit. I deleted my local branch, checked it out again, it is not there. Neither I can find it in the commit history on the git repo.

Neither I see it ending up the changes, so I suppose is not part of the PR.

Maybe I made mistake at some point and falsified the history of the branch. So sorry.

We could maybe update music-metadata to the latest version?

Sounds good to me.

….0' into feature/async-update-music-metadata

# Conflicts:
#	package.json
@mathiasvr
Copy link
Contributor

mathiasvr commented Sep 26, 2018

Although it is depending on the file format and provided settings, music-metadata doesn't read necessary to the end of the stream, in many cases, a relative small portion of the beginning of the stream is sufficient.

Sounds good, in that case I do not see a problem. 👍

I checked my local branch and I cannot find that commit. I deleted my local branch, checked it out again, it is not there. Neither I can find it in the commit history on the git repo.

Yes that looks pretty weird? However I still see it in GitHub changes view, and also when manually pulling your branch to the master.

Can you try to rebase your branch? Otherwise if you check Allow edits from maintainers on this PR, I can try to do it.

@Borewit
Copy link
Member Author

Borewit commented Sep 26, 2018

Oh I see what you mean, it is part of the change-set, overlooked that.

Allow edits from maintainers is and was granted Mathias, be my guest.

This is my last PR on a branch created in my clone, I will use webtorrent repo straight away in the future, much easier.

@mathiasvr mathiasvr merged commit 06566d3 into webtorrent:master Sep 26, 2018
@Borewit
Copy link
Member Author

Borewit commented Sep 27, 2018

Thanks Mathias!

@lock lock bot locked as resolved and limited conversation to collaborators Dec 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants