sigma67 / ytmusicapi Goto Github PK
View Code? Open in Web Editor NEWUnofficial API for YouTube Music
Home Page: https://ytmusicapi.readthedocs.io
License: MIT License
Unofficial API for YouTube Music
Home Page: https://ytmusicapi.readthedocs.io
License: MIT License
When making call: yt.get_watch_playlist()
Error is:
Traceback (most recent call last):
File "ytm-tool.py", line 175, in
main()
File "ytm-tool.py", line 170, in main
do_list(yt,args)
File "ytm-tool.py", line 44, in do_list
do_list_queue(yt,args)
File "ytm-tool.py", line 108, in do_list_queue
history = yt.get_watch_playlist()
File "/home/pi/.local/lib/python3.7/site-packages/ytmusicapi/mixins/watch.py", line 59, in get_watch_playlist
results = response['contents']['singleColumnMusicWatchNextResultsRenderer']['playlist'][
KeyError: 'contents'
Dumping the response output gives:
{'responseContext': {'serviceTrackingParams': [{'params': [{'key': 'c',
'value': 'WEB_REMIX'},
{'key': 'cver',
'value': '0.1'},
{'key': 'yt_li',
'value': '1'},
{'key': 'GetMusicWatchNext_rid',
'value': '0xac85e24a918052a1'}],
'service': 'CSI'},
{'params': [{'key': 'logged_in',
'value': '1'},
{'key': 'e',
'value': '23925759,23931789,23918597,23927190,23940210,23901082,23939002,23934594,9473386,23874981,23899758,23897263,23898478,23927096,23911226,23934047,23925550,23709532,23904038,23857970,9473407,23862025,23927089,23896666,23790586,23861666,23882884,23905281,23910680,23932754,23914966,23921357,23884386,23932567,23937103,23897257,23841635,23908862,23789385,23857949,23937161,23755966,23794339,23932955,23935723,23937384,23884998,23907445,23935184,23898321,23865206,23839597,23927102,23939162,23935178,23934344,23918474,23745613,23921982,23940773,1714252,23936487,23921644,23935545,23837886,23896704,23902702,23910764,23923643,23934322,23797973,23899760,23900854,23934624,39320819,23834232,23864523,23904600,23931540,23919306,23801987,23897295,23862294,23915985,23934014,23884593,23854276,23880323,23919047,23897503,23919917,23899696,23921377,23804281,23832002,24650112,23860381,23934970,23744176,23933618,23928204,23899762,23927208,23894009,23923390,23911301,23928679,23862065,23915932,23836115,23874337,23866675,23936409,23862582,23932706,23932792,23919025,23919895,23938891,23932188,23858564,23933563,23871729,23937610,23862346,23901962,23892622,23918657,23895139,23897872,23935296,23874051,23928508,23853114,23937416,23882125,23935842,23938768,23842638,23886777,23907384,23902008,23856479,23938461,23842233,23872595,23754764,23932183,23925265,23859025,23899764,23936023,9473369,24590231,23934570,23930220,23936677,23911055,23923862,23882685,23868136,23900376,23874940,23900829,23933139,23939497,23939014,23884697,23885639,23811985,23841299,23816681,23910775,23890891,23932752,23865230,23854352,23925932,23927284,23935261,23921992,23938619,23916053,23915032,23929653,23891344,23907436'}],
'service': 'GFEEDBACK'},
{'params': [{'key': 'client.version',
'value': '0.1'},
{'key': 'client.name',
'value': 'WEB_REMIX'}],
'service': 'ECATCHER'}],
'visitorData': },
'trackingParams': }
My script (a scrobbler for lastFm) checks the get_history() function every minute but it just fetched old values? There were several new songs and it shows them in the browser too...
My script: https://gist.github.com/akraus53/ae97d9e4841dd669b920be906318c7be
The log file kept saying the history doesn't have any new entries but the browser did. It started working again an hour later?
Here's an error when uploading a file named: 02 ❦ (Ripe & Ruin).mp3
. I renamed the file to get rid of the weird character, and it uploaded ok.
I'm not sure if in my code I should have done translation before I passed it to ytmusicapi.
Traceback (most recent call last):
File "/home/tony/Sync/projects/ytmusic/ytmusic_uploader.py", line 67, in <module>
main()
File "/home/tony/Sync/projects/ytmusic/ytmusic_uploader.py", line 53, in main
status = ytmusic.upload_song(f)
File "/usr/local/lib/python3.6/dist-packages/ytmusicapi/ytmusic.py", line 458, in upload_song
response = requests.post(upload_url, data=body, headers=headers)
File "/usr/local/lib/python3.6/dist-packages/requests/api.py", line 116, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python3.6/dist-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py", line 603, in urlopen
chunked=chunked)
File "/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py", line 355, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python3.6/http/client.py", line 1254, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib/python3.6/http/client.py", line 1299, in _send_request
body = _encode(body, 'body')
File "/usr/lib/python3.6/http/client.py", line 171, in _encode
(name.title(), data[err.start:err.end], name)) from None
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2766' in position 12: Body ('❦') is not valid Latin-1. Use body.encode('utf-8') if you want to send it encoded in UTF-8
The README stats add/remove library content but from reading the tests and the source I can't figure out how to do this.
Is this not yet implemented or is the library a "playlist" with a special id or something?
Thanks for the help
As title, I don't when will the authentication file expire.
If I create a new authentication json file, it will be ok to run at fist several times. But it will fail to authenticate if I sign out this account at another browser. Or some unknown reasons which will cause this verified authentication json file expired.
Hi,
thanks for your time creating this script.
Can you tell if there is a possibility to get the streaming url for a track like the gmusicapi did?
Greetings,
Andreas
I tried to use this API to upload songs to youtube music. But always fail to do that.
#!/usr/bin/env python3
# -*- coding:UTF-8 -*-
import os
from ytmusicapi import YTMusic
ytmusic = YTMusic('yt_header.json')
file = "test.mp3"
status=ytmusic.upload_song(file)
print(status)
I got return status "STATUS_SUCCEEDED", but I fail to see my uploaded song in youtube music.
200
{'X-GUploader-UploadID': 'AEnB2UpJYZnMeaGnKkJuNPM1Q75X5WaFXkxO8BGfxtUcxjN7tAqhIJysFn3CF5c0zsd2iGteKHcsN87KGhA-qEG-6NMpcnB0i1qEHxyyvOeYh4MSChuPVd4', 'X-Goog-Upload-Status': 'final', 'Content-Length': '0', 'Date': 'Fri, 03 Apr 2020 07:48:50 GMT', 'Server': 'UploadServer', 'Content-Type': 'text/html; charset=UTF-8'}
I tried to do some fail experiments and the return status is always "STATUS_SUCCEEDED"
If I use a loop to upload files in a folder, it will random get response "500" error during file uploading. Need to wait some time (~ 1mins) , and resend X-Goog-Upload-Command
"start", "upload, finalize" request after file uploading got response 500 error. But this not a smart solution and waste upload bandwidth.
I don't know if "OPTION" request is used to communicate with server to check if server is ready for a Upload command.
YTMusic.add_playlist_items(): needs a list of songids.
YTMusic.remove_playlist_items(): needs a list of dictionaries of songids
Why not also use a list of songids for YTMusic.remove_playlist_items(), which is consistent and simpler.
You can choose your favourite artist with this url: https://music.youtube.com/tasteprofile
According to Google it changes to recommendations.
Please add a way to add artists to this list via your api.
Firstly thank you for your great work with ytmusicapi. According to the documentation, I should be able to get metadata about a video, but it seems like that endpoint does not exist in the source code.
AttributeError: 'YTMusic' object has no attribute 'get_song'
I'm currently using ytmusicapi-0.9.1.
Thank you for your attention.
Hi -
Using v 0.9.1. Looking at the JSON for a watch playlist, I'm only seeing shortBylineText
and the parser is looking for longBylineText
. Is this a known issue? (Line numbers will be slightly off as I added some code to output the JSON). You can see the song ID I am using in the tracebak. Happy to provide the full JSON as well.
Traceback (most recent call last):
File "ytmusic_test.py", line 4, in <module>
ytmusic.get_watch_playlist('X3IA6pIVank')
File "/Users/johnmagee2/Documents/PythonEnvironments/ytmusic/lib/python3.8/site-packages/ytmusicapi/mixins/watch.py", line 63, in get_watch_playlist
tracks = parse_watch_playlist(results['contents'])
File "/Users/johnmagee2/Documents/PythonEnvironments/ytmusic/lib/python3.8/site-packages/ytmusicapi/parsers/watch.py", line 14, in parse_watch_playlist
'byline': nav(data, ['longBylineText', 'runs', 0, 'text']),
File "/Users/johnmagee2/Documents/PythonEnvironments/ytmusic/lib/python3.8/site-packages/ytmusicapi/parsers/utils.py", line 75, in nav
raise err
File "/Users/johnmagee2/Documents/PythonEnvironments/ytmusic/lib/python3.8/site-packages/ytmusicapi/parsers/utils.py", line 69, in nav
root = root[k]
KeyError: 'longBylineText'
For authenticated requests, this API currently depends on the browser session that the sesson cookie originates from. If the browser session is invalidated (logout, account switch, expiry), the app will fail to authenticate without a new browser cookie (see also #7).
Ideally this API should have a way to create and renew such a cookie independently. This could be done by providing the user with a link to login, similar to gmusicapi, and storing the provided cookie. As for renewal I'm not sure how this could work, but perhaps it can be reverse engineered from the web app.
Since I am completely unfamiliar with YouTube authentication, I hope someone can help out with this.
I was trying to get my playlists (transfered from gpm in my case) contents using "get_playlist." On some of my playlists it yields the error [Item #: 'NoneType' object is not subscriptable]. I tracked it down to "parse_song_artists" and realized that it was only giving the error for songs that don't have an artist (tracks that I uploaded to gpm with incomplete metadata).
Youtube Music have brand account,and they have another authentification type.If user wil try to authentificate with brand account to current api version it will cause error.I would like to help a bit to find you solution of this problem.As i understood to authentificate brand users properly you will need to add only "onBehalfOfUser" property to "user" class with proper value.
As i understand they get value of this property from this request,but i dont understand what generates body of this request(i assume it generated by javascript)
In next request body already contains this property.And we can find proper onBehalfOfUser value already in response of this request(but mb it also generated by javascript and already known).How to create a brand account you can find by this link https://support.google.com/youtube/answer/1646861?hl=en.
Without onBehalfOfUser property in json it will authentificate to parent account(if you havent created separate brand account,but created just one more channel to existing) or it will throw an exception
When searching for an artist, an exception is thrown if the subheader key is missing in the descriptionShelf.
Artist example:
# Roy Hargrove
ytm.get_artist("UC0twFFwo7-ZajQ7SxgcY6bQ")
Simple fix here
... to_int(descriptionShelf.get('subheader', {'runs': [{'text': '0'}]})['runs'][0]['text'])
Thank you for this wonderful library. I can get music audios, i can get music videos for artist, but is there any way to get music videos bound to albums? I mean get album tracks, and replace music audio with music videos, if they exists. Like in android application, when you play album, or on youtube website — https://www.youtube.com/user/twentyonepilots/playlists this page have "albums" section (if always have it if it's artist channel), and it has music videos. Maybe you can advise some other library for parsing regular youtube pages?
In my project I am using ytmusicapi to fetch full content of the user's library and save it in csv file. Then I can use these csv files to compare changes in my library or find songs removed from youtube etc.
Unfortunately currently it's very unreliable.
For example: In my library currently I have 2040 songs. To get the library songs I call the api with high limit:
api = YTMusic('headers_auth.json')
library_songs = api.get_library_songs(50000)
Everytime I send that request, the number of returned songs is different, it varies between 1800-2035 songs.
I know that the problem is in YTM itself, because I observed the same problem on the web client and it hasn't been fixed on their side for months. YTM should return library songs in chunks containing 25 items, but very often it's less than 25.
In the end, on average, at least 10% of my library is missing, making my scripts kinda useless. The same problem occurs for get_playlist
method.
As a collaborator, I'd like to be able to remove items from a collaborative playlist.
I'm able to do that with this change, but perhaps there is a better way?
In the documentation https://ytmusicapi.readthedocs.io/en/latest/setup.html about setting up the authentication request, an example is given for Firefox browsers. However, I can't set it up for Chrome/Chromium browsers.
Would it be possible to add an example setup for Chrome/Chromium?
I tried the get_artist
and get_album
examples in the documentation, but both seem to be broken. I tried with and without headers_auth.json.
ytmusic = YTMusic()
print(ytmusic.get_artist("UCmMUZbaYdNH0bEd1PAlAqsA"))
print(ytmusic.get_album("OLAK5uy_kGnhwT08mQMGw8fArBowdtlew3DpgUt9c"))
Traceback for get_artist
Traceback (most recent call last):
File "youtube-music-dl.py", line 61, in <module>
print(ytmusic.get_artist("UCmMUZbaYdNH0bEd1PAlAqsA"))
File "/Users/stephenhuan/.local/share/virtualenvs/youtube-music-dl-u083frPF/lib/python3.8/site-packages/ytmusicapi/ytmusic.py", line 302, in get_artist
result['videoId'] = nav(item, TITLE + NAVIGATION_VIDEO_ID)
File "/Users/stephenhuan/.local/share/virtualenvs/youtube-music-dl-u083frPF/lib/python3.8/site-packages/ytmusicapi/parsers.py", line 286, in nav
root = root[k]
KeyError: 'navigationEndpoint'
Traceback for get_album
Traceback (most recent call last):
File "youtube-music-dl.py", line 62, in <module>
print(ytmusic.get_album("OLAK5uy_kGnhwT08mQMGw8fArBowdtlew3DpgUt9c"))
File "/Users/stephenhuan/.local/share/virtualenvs/youtube-music-dl-u083frPF/lib/python3.8/site-packages/ytmusicapi/ytmusic.py", line 374, in get_album
data = nav(response, FRAMEWORK_MUTATIONS)
File "/Users/stephenhuan/.local/share/virtualenvs/youtube-music-dl-u083frPF/lib/python3.8/site-packages/ytmusicapi/parsers.py", line 286, in nav
root = root[k]
KeyError: 'frameworkUpdates'
Operating system is macOS, Python version is 3.8.2, ytmusicapi version is 0.7.1.
first off, huge thanks to sigma67 for taking on this project. i'm an addictive user of google play music, and have been dreading the switch... but thanks to this project i may be able to find a similar satisfaction with YT music in the long run.
this is my first issue, so apologies for any missing/incomplete info. thanks in advance for any assistance you can provide.
i have v0.8.1 installed, and have been poking around learning the usage. when i attempted get_library_songs(), i got the following result:
Traceback (most recent call last):
File "", line 1, in
File "C:\Users\isaacq\AppData\Roaming\Python\Python38\site-packages\ytmusicapi\ytmusic.py", line 554, in get_library_songs
results = nav(results, ITEM_SECTION)['musicShelfRenderer']
KeyError: 'musicShelfRenderer'
In my experimentation auto-generating playlists, I started getting a KeyError from create_playlist().
Traceback (most recent call last):
File "./ytmusic.py", line 153, in <module>
main()
File "./ytmusic.py", line 148, in main
replace_playlist(ytmusic, playlist_name, track_ids)
File "./ytmusic.py", line 124, in replace_playlist
id = ytmusic.create_playlist(title, desc)
File "/usr/local/lib/python3.8/dist-packages/ytmusicapi/ytmusic.py", line 782, in create_playlist
return response['playlistId']
KeyError: 'playlistId'
I stuck a debug in there, and saw this in the JSON response:
{'error': {'code': 429, 'message': 'You are creating too many playlists. Please wait a while before creating further playlists.', 'errors': [{'message': 'You are creating too many playlists. Please wait a while before creating further playlists.', 'domain': 'gdata.CoreErrorDomain', 'reason': 'RATE_LIMIT_EXCEEDED'}], 'status': 'RESOURCE_EXHAUSTED'}}
The python API should probably catch this and return an error code or throw a custom exception.
Using the "Oasis" example given, search('Oasis','artists') returns a browseID of - UCmMUZbaYdNH0bEd1PAlAqsA
This appears correct as per using the web interface which returns - https://music.youtube.com/channel/UCmMUZbaYdNH0bEd1PAlAqsA
attempting to subscribe_artists to this browseId returns success but artist is not subscribed in web interface.
investigation shows that subscribing from the web interface submits a different channelD from what is displayed in the URL and returned in search - UCUDVBtnOQi4c7E8jebpjc9Q
subscribing to this ID via API works, whether you view the artists at:
https://music.youtube.com/channel/UCmMUZbaYdNH0bEd1PAlAqsA
or
https://music.youtube.com/channel/UCUDVBtnOQi4c7E8jebpjc9Q
?!
Unable to find this second ID returned anywhere in search() or via web interface (though it must be somewhere for it to be available to web app to submit)
Have verified this problem with all artists I search for.
If I call get_playlist() on a playlist without a description I get:
Traceback (most recent call last):
File "./ytmusic.py", line 100, in <module>
main()
File "./ytmusic.py", line 71, in main
clear_playlist(ytmusic, playlist_id)
File "./ytmusic.py", line 43, in clear_playlist
playlist = ytmusic.get_playlist(id, limit=100)
File "/usr/local/lib/python3.8/dist-packages/ytmusicapi/ytmusic.py", line 721, in get_playlist
playlist['description'] = header['description']['runs'][0]['text']
KeyError: 'description'
If I fill in a description via the web UI, the call works. After I remove the value in the web UI, the call fails again.
I'm doing a lot of testing on the API this week, hope my filing of issues is helpful and not obnoxious. I know the API is in flux, just adding info as I discover it and happy to help debug or work on PRs although I'm a weak developer.
Until this morning (8/19), get_history()
was excluding non-"song" type YouTube videos, and it is now returning them. In this case videoId jjwilAja7Lc
. I discovered this while trying to pull out the ['artists']
key from the get_song()
JSON.
Not sure if this is really an issue, but it's worth knowing for those who are using the info assuming that a "song" with "artists" is being returned.
I would like to request a feature, which is actually something I've been trying to do with google play music for the last few weeks on and off but couldn't get to work. With Google explaining how to switch to Youtube Music recently, I might as well try getting it to work on YT-music.
I want to log my listening history on LastFM, which is a platform to do exactly that, they call it "scrobbling". I'd be happy to write my own software to do the scrobbling part, but I think this could be a usefull tool for many. Scrobbling is mainly done by reading notifications or by native integration in a player, which is both impossible if you're using a Smart Home Speaker like Chromecast Audio or a Google Home Mini.
Therefore, I'd prefer scrobbling the history from https://music.youtube.com/history
So a feature like ytmusic.get_history(someUnixTimestamp)
would be awesome and ytmusic.autoScrobble()
would be even better.
I might look into this myself, but hell, feel free to implement it yourself.
Thanks a lot
This one is a bit obscure to me.
Simple code:
albums = ytmusic.get_library_upload_albums(limit=10)
albuminfo = ytmusic.get_album(albums[0]['browseId'])
Results in:
Traceback (most recent call last):
File "./ytmusic.py", line 155, in <module>
main()
File "./ytmusic.py", line 145, in main
track_ids = get_random_album_tracks(ytmusic, 2)
File "./ytmusic.py", line 73, in get_random_album_tracks
albuminfo = ytmusic.get_album(albums[0]['browseId'])
File "/usr/local/lib/python3.8/dist-packages/ytmusicapi/ytmusic.py", line 373, in get_album
data = nav(response, FRAMEWORK_MUTATIONS)
File "/usr/local/lib/python3.8/dist-packages/ytmusicapi/parsers.py", line 284, in nav
root = root[k]
KeyError: 'frameworkUpdates'
I dumped the response text from library ytmusic.py:373, and attached.
resp.txt
[Creating ticket per CONTRIBUTING.rst]
Context:
YouTube Music urls already provide the id to the video. It would be nice to be able to fetch a video's metdata, e.g. name, artists from this videoId. Similar to get_album() for albums. get_song(self, videoId)
could return a song's metadata.
How this feature is missing:
From reading the documentation, there doesn't seem to be an endpoint to retrieve this information or a set of chained function calls to achieve this use case.
Acceptance criteria:
This ticket is to gather information on the set of requirements and to implement the method in class YTMusic
, if currently feasible.
This ticket can be closed under any of the following conditions:
get_song(self, videoId)
has been implemented in YTMusic
(with corresponding unit/integration tests) for fetching song metadataI'm not yet sure about the limitations on the api for fetching this information, or futhermore if this would somehow be blocked by #10. I (@JGMEYER) am open to help develop this feature, but may need some guidance.
When uploading a new song using ytmusic.upload_song(), the function should return a songid when succeeded.
Now it only returns STATUS_SUCCEEDED but no id, so you cannot add the song to a playlist afterwards.
There is also no reliable function to retrieve the songid from the song just uploaded (YTMusic.search() is not specific enough and unreliable).
There is only ytmusic.get_library_upload_songs(50000) to retrieve all uploaded songs, but this can take long if you have a large library (a few minutes for a library of 20000 songs.
Can you either fix this or create a function to get the songid of the last uploaded song.
Other option is to create a filter in the YTMusic.search() to get the last uploaded song.
hi
i use this ytmapi.
it's very good api.
but i have some problem about language.
it returns not korean music title or artist name but english music title or artist name.
can i get other langauge's music info not english?
ah.. i use get_history method.
The web UI allows the adding of an uploaded album to a playlist in a single operation. I'm not sure what's happening under the hood, but if it appears that this is also a single operation at the REST level, I'd like to see this implemented in your API.
Otherwise, please discard this request. :-)
Can it download as well?
I've written a Mopidy extension for Youtube Music, using this library, but to be compliant with Mopidy extension guidelines I'd
have to respect global proxy config which is currently not possible.
ytmusicapi seems to use requests under the hood and Mopidy provides proxy config formatted for use with requests,
so all I'd need would be an extra __init__()
param for YTMusic to pass proxy config to requests.
Thanks for this amazing API! I've been uploading my personal music library using the upload_song function, and it's way more convenient than the web UI.
But I've noticed that if I try to run get_uploaded_songs(), I get an error:
Traceback (most recent call last):
File "./ytmusic.py", line 46, in <module>
main()
File "./ytmusic.py", line 39, in main
songs = ytmusic.get_uploaded_songs(1)
File "/usr/local/lib/python3.7/dist-packages/ytmusicapi/ytmusic.py", line 607, in get_uploaded_songs
results = nav(response, SINGLE_COLUMN_TAB + SECTION_LIST + [1] + ITEM_SECTION)['musicShelfRenderer']
File "/usr/local/lib/python3.7/dist-packages/ytmusicapi/helpers.py", line 19, in nav
for k in items: root = root[k]
IndexError: list index out of range
Maybe something on the server side changed since you implemented this?
Thanks for writing this! I was playing around with it and noticed that during setup it does not copy the number from the request header X-Goog-AuthUser.
In the pasted headers from firefox contained:
X-Goog-AuthUser: 2
But the generated header_auth.json was using:
"X-Goog-AuthUser": "0"
This was causing my liked songs, playlists, etc to be pulled from different google account that I don't use with youtube music.
I have a few google accounts. I'm not sure how google handles all that. This particular account is not a brand account, and I didn't notice this in the docs so thought I'd let you know.
I noticed the AuthUser number matches this url when selecting the correct account: https://myaccount.google.com/u/2/?pli=1 (the 2 changes to 0 on my default account).
I changed the value X-Goog-AuthUser to match the firefox request headers and it worked perfectly.
Thanks again! Let me know if you need more info.
Hi, As this is my first issue here, I'd like to thank you for your great work with this api.
In my little project I'd like to upgrade to 0.9.0 version, but then when i run my script, api throws error during import:
File "E:\workspace_ll\ytmusic-lib-tracker\ytmusiclibtracker\export_playlists.py", line 2, in <module>
from ytmusiclibtracker.ytm_api_wrapper import *
File "E:\workspace_ll\ytmusic-lib-tracker\ytmusiclibtracker\ytm_api_wrapper.py", line 1, in <module>
from ytmusicapi import YTMusic
File "C:\Users\Czifumasa\.virtualenvs\ytmusic-lib-tracker-HSFrdYBv\lib\site-packages\ytmusicapi_init_.py", line 2, in <module>
from ytmusicapi.ytmusic import YTMusic
File "C:\Users\Czifumasa\.virtualenvs\ytmusic-lib-tracker-HSFrdYBv\lib\site-packages\ytmusicapi\ytmusic.py", line 11, in <module>
from ytmusicapi.mixins.browsing import BrowsingMixin
ModuleNotFoundError: No module named 'ytmusicapi.mixins'
On 0.8.1 version everything worked correctly. When I checked installed ytmusicapi package content from pypi, folder mixins
is missing in 0.9.0 realease.
My OS: Windows 10, Python: 3.8.2, ytmusicapi: 0.9.0
hi i'm interested in this api
but, i don't understand below word
Go to the developer tools (Ctrl-Shift-I) and find an authenticated POST request. You can filter for /browse to easily find a suitable request.
i open ytm in firefox. then input ctrl+shift+i.
how can i find an authenticated POST request...?
and this step is before login ytm or after login ytm?
Hey, thanks for this awesome API, I'm using it to write some simple scripts for my library. I ran into an issue when I tried to run get_playlist() on a pl with >1,000 songs. Looks like the comma needs to be stripped out of the song count.
Traceback (most recent call last):
File "simple-playlist-maker.py", line 38, in
pl_tracks = ytmusic.get_playlist(playlist, 9999)["tracks"]
File "/home/hibby/.local/lib/python3.8/site-packages/ytmusicapi/ytmusic.py", line 732, in get_playlist
song_count = int(header['secondSubtitle']['runs'][0]['text'].split(' ')[0])
ValueError: invalid literal for int() with base 10: '1,149'
Code to reproduce
import os, json
from ytmusicapi import YTMusic
conf_file = os.path.dirname(__file__)+'/headers_auth.json'
ytmusic = YTMusic(conf_file)
result = ytmusic.get_artist('UCBQZwaNPFfJ1gZ1fLZpAEGw')
print(json.dumps(result, indent=2))
doesn't have "videos" section, although youtube music page and android app have it.
a little issue at request body which is not default Latin-1
encoded.
add body = body.encode(encoding='utf-8')
after line 453 of ytmusic.py could solve my problem.
The library should provide functionality to browse artists and albums on YouTube Music.
The current proposed method outline is as follows (open to suggestions, improvements etc):
get_artist(channelId)
should return a dictionary with lists of songs, albums, singles, videos on the artist page
should also return info to get more songs/albums if available (i.e. the playlistId)
get_artist_songs(playlistId)
should get all songs by an artist
playlistId provided by get_artist
get_artist_albums(channelId, params)
should get singles or albums depending on the params
the required params should be provided by get_artist
get_album(browseId)
should get all songs for an album. the method for converting between browseId and playlistId that you mentioned should be quite helpful here
The docstring for get_playlist
says it returns a list of playlistItem dictionaries.
I'm only get a dictionary back...not wrapped in a list. Is it possible for a playlistId
to return multiple playlistItem
dictionaries? I don't have enough experience with the API yet to know if it'll ever return a list, but even if it sometimes returns a list and sometimes a dictionary the docstring seems to be incorrect.
According to Google songs played change the recommendation:
https://support.google.com/youtubemusic/thread/160722?hl=en
Would it be possible adding a delete_song_history() function?
I am creating a tool called WinaYo (Winamp to Youtube Music) to convert and import WinAmp playlists (m3u8) to Youtube Music playLists (csv) using YTMusicapi. Everything is almost ready now and I started live testing with a big WinAmp library (22800 songs, 108 playlists, some playlists have over 5000 songs).
While creating the Youtube Music playlists with WinaYo, I now ran into what seems the quota limits for YTMusicapi (or Youtubeapi?): Can't create/delete playlists no more.
What are the quota-limits for YTMusicapi/Youtubeapi calls? I read somewhere that it was recently reduced from 1000000 to 40000 calls (7/9/19). Is that per day/month? Any clues? Any clues how to reset or ask for or set higher quota's?
Hey! Thanks for this project, searched for YTM API a while ago and couldn't find anything.
I needed some API actions for my use case, so I successfully reverse-engineered the following YTM functionality:
and two functions for getting playlistIds from browseIds for artists and albums, which are respectively needed for retrieving artist page and manipulating albums in library.
So, given that, we need to write the rules/info on how should the perfect PR look:
Once again thank you 😄
I try to get the dict info from an uploaded song, but for all uploaded songids I try, I get the same error.
Here is the content of my test python script isolating the problem:
from ytmusicapi import YTMusic
ytmusic = YTMusic('headers_auth.json')
song = ytmusic.get_song("kLXRb5ah7Fo")
print(song)
And this is the error it generates no matter what uploaded songid I specify:
Traceback (most recent call last):
File "F:\Develop\test.py", line 3, in <module>
song = ytmusic.get_song("kLXRb5ah7Fo")
File "F:\Python38.32\lib\site-packages\ytmusicapi\mixins\browsing.py", line 535, in get_song
song_meta['streamingData'] = player_response['streamingData']
KeyError: 'streamingData'
What is the reason?
ps. all my other calls creating playlists, adding songs to playlists etc. work perfectly
ps. for public songs, the call works ok
ps. i need this function to remove songs from an existing playlist (YTMusic.remove_playlist_items)
Pulling album details may fail if musicTrackUserDetails aren't present
Possible fix here
track['likeStatus'] = likes.get(item['entityKey'], 'INDIFFERENT')
for videoId dyG_yptc7y8
I get the below error. Out of 10 songs I was just looking at, this was the only error (I am working around it by catching and IndexError
and putting song_meta['production'] = 'No info'
for this line)
Traceback (most recent call last):
File "ytmusic_manager.py", line 148, in <module>
y.print_history()
File "ytmusic_manager.py", line 84, in print_history
song = self.get_song(entry)
File "/Projects/ytmusic_manager/ytmusicapi/ytmusicapi/mixins/browsing.py", line 531, in get_song
song_meta['production'] = [pub for pub in description[5].split('\n')]
IndexError: list index out of range
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.