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

recognize_song raises FileNotFoundError even if file is present #9

Closed
SetUpSim opened this issue Jun 27, 2021 · 8 comments
Closed

recognize_song raises FileNotFoundError even if file is present #9

SetUpSim opened this issue Jun 27, 2021 · 8 comments

Comments

@SetUpSim
Copy link

SetUpSim commented Jun 27, 2021

I'm writing a Teleram bot with Shazam-like functionality. Under the hood it downloads the file or voice message sent by user, gets its path and tries to recognize the song from file located on that path.

My code:

import telebot
import requests
import asyncio
from shazamio import Shazam

TOKEN = None

with open("TOKEN") as f:
    TOKEN = f.read().strip()

bot = telebot.TeleBot(TOKEN, parse_mode=None)

def download_file_and_return_name(file_id):
    file_info = bot.get_file(file_id)
    filename = file_info.file_path.split("/")[-1]
    resp = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(TOKEN, file_info.file_path))
    with open(filename, "wb") as f:
        f.write(resp.content)
    return filename

async def recognize(path):
    shazam = Shazam()
    print(path)
    print(os.path.exists(path))
    out = await shazam.recognize_song(path)
    print(out)


@bot.message_handler(content_types=["audio", "voice"])
def handle_audio(message):
    filename = download_file_and_return_name(message.voice.file_id if message.content_type == "voice" else message.audio.file_id)
    # loop = asyncio.get_event_loop()
    # loop.run_until_complete(recognize(filename))
    asyncio.run(recognize(filename))

bot.polling()

Unfortunately, recognize_song(file_path) method raises FileNotFoundError even if file is present, which is logged by print(os.path.exists(path))
Console log:

C:\Users\stass\workspace\shazamBotProject\venv\Scripts\python.exe C:/Users/stass/workspace/shazamBotProject/main.py
C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\pydub\utils.py:170: RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work
  warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning)
file_40.oga
True
C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\pydub\utils.py:198: RuntimeWarning: Couldn't find ffprobe or avprobe - defaulting to ffprobe, but may not work
  warn("Couldn't find ffprobe or avprobe - defaulting to ffprobe, but may not work", RuntimeWarning)
Traceback (most recent call last):
  File "C:\Users\stass\workspace\shazamBotProject\main.py", line 42, in <module>
    bot.polling()
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\telebot\__init__.py", line 514, in polling
    self.__threaded_polling(none_stop, interval, timeout, long_polling_timeout)
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\telebot\__init__.py", line 573, in __threaded_polling
    raise e
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\telebot\__init__.py", line 536, in __threaded_polling
    self.worker_pool.raise_exceptions()
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\telebot\util.py", line 117, in raise_exceptions
    raise self.exception_info
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\telebot\util.py", line 69, in run
    task(*args, **kwargs)
  File "C:\Users\stass\workspace\shazamBotProject\main.py", line 40, in handle_audio
    asyncio.run(recognize(filename))
  File "C:\Users\stass\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\stass\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete
    return future.result()
  File "C:\Users\stass\workspace\shazamBotProject\main.py", line 30, in recognize
    out = await shazam.recognize_song("file_35.ogg")
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\shazamio\api.py", line 220, in recognize_song
    audio = self.normalize_audio_data(file)
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\shazamio\converter.py", line 45, in normalize_audio_data
    audio = AudioSegment.from_file(BytesIO(song_data))
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\pydub\audio_segment.py", line 685, in from_file
    info = mediainfo_json(orig_file, read_ahead_limit=read_ahead_limit)
  File "C:\Users\stass\workspace\shazamBotProject\venv\lib\site-packages\pydub\utils.py", line 274, in mediainfo_json
    res = Popen(command, stdin=stdin_parameter, stdout=PIPE, stderr=PIPE)
  File "C:\Users\stass\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 947, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\stass\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1416, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified

Process finished with exit code 1

I haven't used the loop = asyncio.get_event_loop() loop.run_until_complete(main()) construct from the example because it raises RuntimeError: There is no current event loop in thread 'WorkerThread2'

@dotX12
Copy link
Collaborator

dotX12 commented Jun 28, 2021

@SetUpSim, Hello!

I have a question for you:
If you are using the Telebot library, why are you sending a naked request to API telegram, this library already has methods for downloading files.

I already have a project that you want to implement:
https://github.com/dotX12/ShazamBot

An asynchronous library for working with telegram is used here (aiogram).

@SetUpSim
Copy link
Author

SetUpSim commented Jun 28, 2021

A piece of Telebot documentation:

# getFile
# Downloading a file is straightforward
# Returns a File object
import requests
file_info = tb.get_file(file_id)

file = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(API_TOKEN, file_info.file_path))

So I'm sending a naked request to Telegram API to download files because Telebot appears to have no API method for doing this.
Thank you for your advice on aiogram, but I'm currently mastering another library. And here a strange bug reveals, so I would like you to maybe clear the things out for me.

@dotX12
Copy link
Collaborator

dotX12 commented Jun 28, 2021

@SetUpSim,
In fact, I changed almost nothing, your code worked for me, only changed the launch of an asynchronous function in a loop.
https://carbon.now.sh/qH4Jci9HPh2uboq9tNDz

image

@dotX12
Copy link
Collaborator

dotX12 commented Jun 28, 2021

Console:

image

File hierarchy:

image

@SetUpSim SetUpSim reopened this Jun 28, 2021
@SetUpSim
Copy link
Author

@dotX12 Your code still raises FileNotFoundError for me.
What's your Python version? Mine is 3.9.0

@dotX12
Copy link
Collaborator

dotX12 commented Jun 28, 2021

Check if your files are saved?
If so, maybe they will be saved to a different location, relative to your bot file.

@dotX12
Copy link
Collaborator

dotX12 commented Jun 29, 2021

@SetUpSim, Ahhh, sorry man...

RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work
  warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning)
  

You need to install ffmpeg.

@SetUpSim
Copy link
Author

Yep, that was the thing. Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants