
Recherche avancée
Médias (1)
-
Revolution of Open-source and film making towards open film making
6 octobre 2011, par
Mis à jour : Juillet 2013
Langue : English
Type : Texte
Autres articles (47)
-
Gestion générale des documents
13 mai 2011, parMédiaSPIP ne modifie jamais le document original mis en ligne.
Pour chaque document mis en ligne il effectue deux opérations successives : la création d’une version supplémentaire qui peut être facilement consultée en ligne tout en laissant l’original téléchargeable dans le cas où le document original ne peut être lu dans un navigateur Internet ; la récupération des métadonnées du document original pour illustrer textuellement le fichier ;
Les tableaux ci-dessous expliquent ce que peut faire MédiaSPIP (...) -
Des sites réalisés avec MediaSPIP
2 mai 2011, parCette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page. -
HTML5 audio and video support
13 avril 2011, parMediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
For older browsers the Flowplayer flash fallback is used.
MediaSPIP allows for media playback on major mobile platforms with the above (...)
Sur d’autres sites (3043)
-
Path and bundle strings have different number of entries ; invalid manifest : xuggle-xuggler
7 décembre 2013, par henrycharlesI am new to multimedia.I want to make a project for live video chat in java. Googling around I found about Xuggler.I successfully downloaded all the jars given in this How do you install the latest version of Xuggler (5.4, as of 18/05/2013) in eclipse ? .
and tried executing sample code from http://www.javacodegeeks.com/2011/02/xuggler-tutorial-frames-capture-video.html I am not getting any compilation error but the following runtime error. Any help would be much appreciated.
com.xuggle.ferry.JNIManifest - path and bundle strings have different number of entries ; invalid manifest : xuggle-xuggler
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global;
public class ABC {
public static final double SECONDS_BETWEEN_FRAMES = 10;
private static final String inputFilename = "D://ab.mp4";
private static final String outputFilePrefix = "c://snapshots//mysnapshot";
// The video stream index, used to ensure we display frames from one and
// only one video stream from the media container.
private static int mVideoStreamIndex = -1;
// Time of last frame write
private static long mLastPtsWrite = Global.NO_PTS;
public static final long MICRO_SECONDS_BETWEEN_FRAMES =
(long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);
public static void main(String[] args) {
IMediaReader mediaReader = ToolFactory.makeReader(inputFilename);
// stipulate that we want BufferedImages created in BGR 24bit color space
mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
mediaReader.addListener(new ImageSnapListener());
// read out the contents of the media file and
// dispatch events to the attached listener
while (mediaReader.readPacket() == null) ;
}
private static class ImageSnapListener extends MediaListenerAdapter {
public void onVideoPicture(IVideoPictureEvent event) {
if (event.getStreamIndex() != mVideoStreamIndex) {
// if the selected video stream id is not yet set, go ahead an
// select this lucky video stream
if (mVideoStreamIndex == -1)
mVideoStreamIndex = event.getStreamIndex();
// no need to show frames from this video stream
else
return;
}
// if uninitialized, back date mLastPtsWrite to get the very first frame
if (mLastPtsWrite == Global.NO_PTS)
mLastPtsWrite = event.getTimeStamp() - MICRO_SECONDS_BETWEEN_FRAMES;
// if it's time to write the next frame
if (event.getTimeStamp() - mLastPtsWrite >=
MICRO_SECONDS_BETWEEN_FRAMES) {
String outputFilename = dumpImageToFile(event.getImage());
// indicate file written
double seconds = ((double) event.getTimeStamp()) /
Global.DEFAULT_PTS_PER_SECOND;
System.out.printf(
"at elapsed time of %6.3f seconds wrote: %s\n",
seconds, outputFilename);
// update last write time
mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;
}
}
private String dumpImageToFile(BufferedImage image) {
try {
String outputFilename = outputFilePrefix +
System.currentTimeMillis() + ".png";
ImageIO.write(image, "png", new File(outputFilename));
return outputFilename;
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
} -
ffmpeg stream Windows 7 desktop to Youtube give invalid argument
11 juin 2021, par TenGI am experimenting with live streaming my Windows 7 desktop to YouTube.


Firstly the list of devices :


ffmpeg-N-100616-gca21cb1e36-win64-gpl\bin\ffmpeg.exe -list_devices true -f dshow -i dummy


Gives :


ffmpeg version N-100616-gca21cb1e36 Copyright (c) 2000-2021 the FFmpeg developers
 built with gcc 9.3-win32 (GCC) 20200320
 configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --a
rch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv
--enable-zlib --enable-libxml2 --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-open
cl --enable-libvmaf --disable-vulkan --enable-libvorbis --enable-amf --enable-libaom --enable-avisynth --enable-libdav1d --enable-li
bdavs2 --enable-ffnvcodec --enable-cuda-llvm --disable-libglslang --enable-libass --enable-libbluray --enable-libmp3lame --enable-li
bopus --enable-libtheora --enable-libvpx --enable-libwebp --enable-libmfx --enable-libopencore-amrnb --enable-libopencore-amrwb --en
able-libopenjpeg --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-
libsvtav1 --enable-libtwolame --enable-libuavs3d --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-li
bxvid --enable-libzimg --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-libs=-lgomp
 libavutil 56. 63.100 / 56. 63.100
 libavcodec 58.116.100 / 58.116.100
 libavformat 58. 65.101 / 58. 65.101
 libavdevice 58. 11.103 / 58. 11.103
 libavfilter 7. 95.100 / 7. 95.100
 libswscale 5. 8.100 / 5. 8.100
 libswresample 3. 8.100 / 3. 8.100
 libpostproc 55. 8.100 / 55. 8.100
[dshow @ 000000000052ca00] DirectShow video devices (some may be both video and audio devices)
[dshow @ 000000000052ca00] "VF0700 Live! Cam Chat HD"
[dshow @ 000000000052ca00] Alternative name "@device_pnp_\\?\usb#vid_041e&pid_4088&mi_00#7&b015b04&0&0000#{65e8773d-8f56-11d0-a3
b9-00a0c9223196}\global"
[dshow @ 000000000052ca00] "UScreenCapture"
[dshow @ 000000000052ca00] Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\UScreenCapture"
[dshow @ 000000000052ca00] "screen-capture-recorder"
[dshow @ 000000000052ca00] Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\{4EA69364-2C8A-4AE6-A561-56E4B504
4439}"
[dshow @ 000000000052ca00] DirectShow audio devices
[dshow @ 000000000052ca00] "Microphone (VF0700 Live! Cam Ch"
[dshow @ 000000000052ca00] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Microphone (VF0700 Live! Cam Ch"
[dshow @ 000000000052ca00] "virtual-audio-capturer"
[dshow @ 000000000052ca00] Alternative name "@device_sw_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\{8E146464-DB61-4309-AFA1-3578E927
E935}"
dummy: Immediate exit requested



ffmpeg-N-100616-gca21cb1e36-win64-gpl\bin\ffmpeg.exe -list_devices true -f dshow -i dummy


gives :


ffmpeg version 4.3.1-2021-01-01-full_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers
 built with gcc 10.2.0 (Rev5, Built by MSYS2 project)
 configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enab
le-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-libsrt --enable-libss
h --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-li
brav1e --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --en
able-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-
amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libm
fx --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-
libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb
--enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable
-librubberband --enable-libsoxr --enable-chromaprint
 libavutil 56. 51.100 / 56. 51.100
 libavcodec 58. 91.100 / 58. 91.100
 libavformat 58. 45.100 / 58. 45.100
 libavdevice 58. 10.100 / 58. 10.100
 libavfilter 7. 85.100 / 7. 85.100
 libswscale 5. 7.100 / 5. 7.100
 libswresample 3. 7.100 / 3. 7.100
 libpostproc 55. 7.100 / 55. 7.100
[dshow @ 0000000000485ac0] DirectShow video devices (some may be both video and audio devices)
[dshow @ 0000000000485ac0] "VF0700 Live! Cam Chat HD"
[dshow @ 0000000000485ac0] Alternative name "@device_pnp_\\?\usb#vid_041e&pid_4088&mi_00#7&b015b04&0&0000#{65e8773d-8f56-11d0-a3
b9-00a0c9223196}\global"
[dshow @ 0000000000485ac0] "UScreenCapture"
[dshow @ 0000000000485ac0] Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\UScreenCapture"
[dshow @ 0000000000485ac0] "screen-capture-recorder"
[dshow @ 0000000000485ac0] Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\{4EA69364-2C8A-4AE6-A561-56E4B504
4439}"
[dshow @ 0000000000485ac0] DirectShow audio devices
[dshow @ 0000000000485ac0] "Microphone (VF0700 Live! Cam Ch"
[dshow @ 0000000000485ac0] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Microphone (VF0700 Live! Cam Ch"
[dshow @ 0000000000485ac0] "virtual-audio-capturer"
[dshow @ 0000000000485ac0] Alternative name "@device_sw_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\{8E146464-DB61-4309-AFA1-3578E927
E935}"
dummy: Immediate exit requested



Now trying to live stream with the command :


ffmpeg-N-100616-gca21cb1e36-win64-gpl\bin\ffmpeg.exe -f dshow -i video='screen-capture-recorder':audio='Microphone (VF0700 Live! Cam Ch' -r 24 -s 1920x1080 -qmin 3 'rtmp://a.rtmp.youtube.com:1935/live2/the-stream-key'


I get :


ffmpeg version 4.3.1-2021-01-01-full_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers
 built with gcc 10.2.0 (Rev5, Built by MSYS2 project)
 configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enab
le-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-libsrt --enable-libss
h --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-li
brav1e --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --en
able-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-
amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libm
fx --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-
libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb
--enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable
-librubberband --enable-libsoxr --enable-chromaprint
 libavutil 56. 51.100 / 56. 51.100
 libavcodec 58. 91.100 / 58. 91.100
 libavformat 58. 45.100 / 58. 45.100
 libavdevice 58. 10.100 / 58. 10.100
 libavfilter 7. 85.100 / 7. 85.100
 libswscale 5. 7.100 / 5. 7.100
 libswresample 3. 7.100 / 3. 7.100
 libpostproc 55. 7.100 / 55. 7.100
leaving aero onGuessed Channel Layout for Input Stream #0.1 : stereo
Input #0, dshow, from 'video=screen-capture-recorder:audio=Microphone (VF0700 Live! Cam Ch':
 Duration: N/A, start: 758394.360000, bitrate: N/A
 Stream #0:0: Video: rawvideo, bgr0, 1920x1080, 30 fps, 30 tbr, 10000k tbn, 10000k tbc
 Stream #0:1: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
[NULL @ 00000000006645c0] Unable to find a suitable output format for 'rtmp://a.rtmp.youtube.com:1935/live2/the-stream-key
'
rtmp://a.rtmp.youtube.com:1935/live2/the-stream-key: Invalid argument
[dshow @ 0000000000607400] real-time buffer [screen-capture-recorder] [video input] too full or near too full (545% of size: 3041280
 [rtbufsize parameter])! frame dropped!
 Last message repeated 5 times




In short the errors are :


[NULL @ 00000000006645c0] Unable to find a suitable output format for 'rtmp://a.rtmp.youtube.com:1935/live2/the-stream-key
'
rtmp://a.rtmp.youtube.com:1935/live2/the-stream-key: Invalid argument
[dshow @ 0000000000607400] real-time buffer [screen-capture-recorder] [video input] too full or near too full (545% of size: 3041280



I have tried with and without the
:1935
port number, withffmpeg_x64.exe
but no difference. Is the stream key theinvalid argument
or something else ?

-
How do i properly setup ffmpeg and fix this "Permission Denied" error im getting ?
8 décembre 2020, par ExaNoriError im getting

C:/Users/Motzumoto/Desktop/AGB/ffmpeg/bin: Permission denied


I already have ffmpeg installed to path on my windows 10 machine, but that didnt fix it, so i just tried to put ffmpeg in my bots directory, that didnt do it either.
Heres my music code if anyone can help
It uses a mixture of youtube-dl and ffmpeg
If there are also any errors that would stop this from working at all it'd be nice if you could show me them, im quite tired of this as of now and im honestly just about to scrap this idea and forget about it


I've tried linking the path to the ffmpeg.exe, that still didnt work, i got the same error, i have no idea what to do


import asyncio
import logging
import math
from urllib import request

import discord
from discord.ext import commands
import youtube_dl
from utils.guilds import Guilds
import ffmpeg
from asyncio import run_coroutine_threadsafe as coroutine

DOWNLOAD_PATH = "audio" # download path of the file
STREAM_INDICATOR_PREFIX = "${STREAM}:"




# options
ytdl_options = {
 "quiet": True,
 "forceipv4": True,
 "noplaylist": True,
 "no_warnings": True,
 "ignoreerrors": True,
 "nooverwrites": True,
 "restrictfilenames": True,
 "nocheckcertificate": True,
 "default_search": "auto",
 "format": "bestaudio/best",
}
ffmpeg_options = {
 "options": "-vn" # indicates that we have disabled video recording in the output file
}

ytdl = youtube_dl.YoutubeDL(ytdl_options) # youtube_dl object

# checks functions
def is_connected(ctx):
 """Check if the bot is connected to a voice channel."""
 
 if ctx.voice_client:
 return True
 
 return False
def is_same_channel(ctx):
 """Check if the bot and the user is in the same channel."""
 
 # try to get their voice channel id if there's any
 try:
 bot_channel_id = ctx.voice_client.channel.id
 user_channel_id = ctx.author.voice.channel.id
 # if one of them is not connected to a voice channel then they're not together
 except AttributeError:
 return False
 
 # check if their voice channel id is the same
 if bot_channel_id == user_channel_id:
 return True
 
 return False
async def checks(ctx):
 """Do some checking."""
 
 # check if the user and the bot is in the same channel
 if not is_same_channel(ctx):
 await ctx.send("I am not with you. How dare you to command me like that.")
 return False
 
 return True

# other function
async def create_source(ctx, query):
 """Creates youtube_dl audio source for discord.py voice client."""
 
 try:
 async with ctx.typing(): # shows that the bot is typing in chat while searching for an audio source
 source = await YTDLSource.from_url(query, ctx.bot.loop) # creates a youtube_dl source
 except IndexError: # if found nothing
 await ctx.send("I found nothing with the given query..")
 return None
 
 return source

class Music(commands.Cog, name="music"):
 def __init__(self, bot):
 self.bot = bot
 self.guilds = Guilds() # collection of some guilds that this bot is currently in
 
 async def cog_command_error(self, ctx, error):
 """Catch all errors of this cog."""
 
 # a check on a command has failed
 if isinstance(error, commands.CheckFailure):
 await ctx.send("I'm not connected to any voice channel.")
 # ignore this error because it is already handled at the command itself
 elif isinstance(error, commands.errors.BadArgument):
 pass
 # otherwise, log all the other errors
 else:
 music_logger.exception(error)
 await ctx.send(error)
 
 @commands.command()
 async def join(self, ctx):
 """Invite me to your voice channel."""
 
 try:
 async with ctx.typing(): # shows that the bot is typing in chat while joining the voice channel
 await ctx.author.voice.channel.connect()
 await ctx.send("Alright, I joined your voice channel.")
 # user is not yet connected to a voice channel
 except AttributeError:
 await ctx.send(f"You must be connected to a voice channel first {ctx.author.name}.")
 # bot is already connected to a voice channel
 except discord.ClientException:
 if is_same_channel(ctx):
 await ctx.send("I'm already with you.")
 else:
 await ctx.send("I'm already with somebody else.")
 
 @commands.command()
 @commands.check(is_connected)
 async def leave(self, ctx):
 """Kick me out of your voice channel."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 # reset some bot's states
 self.guilds(ctx).has_played_voice = False # reset 'has_played_voice' state
 self.guilds(ctx).queue.clear() # reset the queue
 
 # finally, stop and disconnect the bot
 ctx.voice_client.stop() # stop the bot's voice
 await ctx.voice_client.disconnect() # disconnect the bot from voice channel
 await ctx.send("Ah, alright, cya.")
 
 async def play_source(self, ctx, vc, source):
 """Play an audio to a voice channel."""
 
 def play_next(error):
 """Executes when the voice client is done playing."""
 
 # log the errors if there is any
 if error:
 music_logger.exception(error)
 coroutine(ctx.send(error), self.bot.loop)
 
 # ensure that there is a song in queue
 if self.guilds(ctx).queue.queue:
 coroutine(ctx.invoke(self.bot.get_command("next")), self.bot.loop) # go to the next song
 
 vc.play(source, after=play_next) # play the voice to the voice channel
 await ctx.send(f"Now playing '{source.title}'.")
 
 @commands.command(aliases=("p", "stream"))
 async def play(self, ctx, *, query=""):
 """Play a song for you."""
 
 # check if the query argument is empty
 if not query:
 # if yes, cancel this command
 await ctx.send("What should I play?")
 return
 
 # check if this command is invoked using 'stream' alias
 if ctx.invoked_with == "stream":
 SIP = STREAM_INDICATOR_PREFIX # put prefix to the title of the source that indicates that it must be streamed
 else:
 SIP = ""
 
 # ensure that the bot is connected a voice channel
 try:
 # connect the bot to the user voice channel
 await ctx.author.voice.channel.connect()
 except AttributeError:
 # user is not yet connected to a voice channel
 await ctx.send(f"You must be connected to a voice channel first {ctx.author.name}.")
 return
 except discord.ClientException:
 pass # just ignore if bot is already connected to the voice channel
 
 # do some other checking before executing this command
 if not await checks(ctx):
 return
 
 # create the audio source
 source = await create_source(ctx, SIP + query)
 
 # ensure that there is actually a source
 if source:
 # initialize bot's states if the the queue is still empty
 if not self.guilds(ctx).queue.queue:
 self.guilds(ctx).has_played_voice = True # this means that the bot has played in the voice at least once
 self.guilds(ctx).queue.enqueue(SIP + source.title)
 
 # play the audio
 try:
 await self.play_source(ctx, ctx.voice_client, source)
 # enqueue the source if audio is already playing
 except discord.ClientException:
 self.guilds(ctx).queue.enqueue(SIP + source.title)
 await ctx.send(f"'{source.title}' is added to the queue.")
 
 @commands.command()
 @commands.check(is_connected)
 async def volume(self, ctx, *, vol=None):
 """Adjust my voice volume."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 vc = ctx.voice_client # get the voice client
 
 # ensure that the bot is playing voice in order to change the volume
 if not self.guilds(ctx).has_played_voice:
 await ctx.send("I haven't even started yet.")
 return
 elif vc.source is None:
 await ctx.send("I am not playing anything.")
 return
 
 # check if user has passed an argument
 if vol is None:
 await ctx.send("I expect an argument from 0 to 100.")
 return
 
 # cast string argument 'vol' into a float
 try:
 vol = float(vol)
 # except if the argument is not a number
 except ValueError:
 await ctx.send("The argument must only be a number.")
 return
 
 # set the volume
 if vol >= 0 and vol <= 100: # bound the volume from 0 to 100
 vc.source.volume = vol / 100
 else:
 await ctx.send("I expect a value from 0 to 100.")
 
 @commands.command()
 @commands.check(is_connected)
 async def pause(self, ctx):
 """Pause the song."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 vc = ctx.voice_client # get the voice client
 
 # ensure that the bot's voice is playing in order to pause
 if vc.is_playing():
 vc.pause()
 await ctx.send("Alright, paused.")
 # the bot haven't played yet
 elif not self.guilds(ctx).has_played_voice:
 await ctx.send("I haven't even started yet.")
 # there is no song in queue
 elif not self.guilds(ctx).queue.queue:
 await ctx.send("I am not playing anything.")
 else:
 await ctx.send("I already paused.")
 
 @commands.command()
 @commands.check(is_connected)
 async def resume(self, ctx):
 """Resume the song."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 vc = ctx.voice_client # get the voice client
 
 # ensure that the bot's voice is paused in order to resume
 if vc.is_paused():
 vc.resume()
 await ctx.send("Alright, song resumed")
 # the bot haven't played yet
 elif not self.guilds(ctx).has_played_voice:
 await ctx.send("I haven't even started yet.")
 # there is no song in queue
 elif not self.guilds(ctx).queue.queue:
 await ctx.send("I am not playing anything.")
 else:
 await ctx.send("I am not paused.")
 
 async def update_song(self, ctx):
 """Change the currently playing song."""
 
 vc = ctx.voice_client # get the voice client
 current = self.guilds(ctx).queue.current # get the current song in queue if there's any
 
 # ensure that the queue is not empty
 if current:
 source = await create_source(ctx, current) # create the audio source
 # the bot haven't played yet
 elif not self.guilds(ctx).has_played_voice:
 await ctx.send("I haven't even started yet.")
 return
 else:
 vc.stop() # stop the voice just to be sure
 await ctx.send("No more songs unfortunately.")
 return
 
 # if voice client is already playing, just change the source
 if vc.is_playing():
 vc.source = source
 await ctx.send(f"Now playing '{source.title}'.")
 # otherwise, play the source
 else:
 await self.play_source(ctx, vc, source)
 
 @commands.command()
 @commands.check(is_connected)
 async def next(self, ctx):
 """Skip the current song."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 self.guilds(ctx).queue.shift(1) # shift the queue to the left
 await self.update_song(ctx) # change the current song
 
 @commands.command()
 @commands.check(is_connected)
 async def prev(self, ctx):
 """Go back to the previous song."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 self.guilds(ctx).queue.shift(-1) # shift the queue to the right
 await self.update_song(ctx) # change the current song
 
 @commands.command()
 @commands.check(is_connected)
 async def removesong(self, ctx, *, index=1):
 """Remove a song in the queue."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 index -= 1 # decrement the 'index' to match the zero-based index of Python
 
 # if index is equal to 0, that means remove the currently playing song
 # do some extra stuff before removing the current song
 if index == 0:
 # try to remove a song in queue
 try:
 self.guilds(ctx).queue.dequeue() # dequeue a song in the queue
 self.guilds(ctx).queue.shift(-1) # shift the queue to the right so that the next song will be played instead of the next next song
 await ctx.invoke(self.bot.get_command("next")) # finally, play the next song
 # except when the queue is empty
 except IndexError:
 await ctx.send("I haven't even started yet.")
 # otherwise, just remove a song in queue
 else:
 # try to remove the song in queue
 try:
 self.guilds(ctx).queue.pop(index)
 await ctx.send("Song removed")
 # except if the song is not in the queue
 except IndexError:
 # check if the bot has not started playing yet
 if not self.guilds(ctx).has_played_voice:
 await ctx.send("I haven't even started yet...")
 else:
 await ctx.send(f"I can't remove that {ctx.author.name} because it doesn't exist.")
 @removesong.error
 async def remove_error(self, ctx, error):
 """Error handler for the 'remove' command."""
 
 # check if the argument is bad
 if isinstance(error, commands.errors.BadArgument):
 await ctx.send(f"I can't remove that {ctx.author.name}.")
 await ctx.send("The argument must only be a number or leave it none.")
 
 @commands.command()
 @commands.check(is_connected)
 async def stop(self, ctx):
 """Stop all the songs."""
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 vc = ctx.voice_client # get the voice client
 
 # ensure that the bot is connected to the voice client
 if vc.is_playing() or vc.is_paused():
 self.guilds(ctx).queue.clear() # reset the queue
 ctx.voice_client.stop() # stop the bot's voice
 await ctx.send("Playback stopped")
 # the bot haven't played yet
 elif not self.guilds(ctx).has_played_voice:
 await ctx.send("I haven't even started yet.")
 else:
 await ctx.send("I already stopped.")
 
 @commands.command()
 @commands.check(is_connected)
 async def queue(self, ctx):
 """Show the queue of songs."""
 
 SIP = STREAM_INDICATOR_PREFIX # shorten the variable name
 
 # do some checking before executing this command
 if not await checks(ctx):
 return
 
 # try to send the songs in the queue
 try:
 # format the queue to make it readable
 queue = [
 f"{i}." + (" (STREAM) " if q.startswith(SIP) else " ") + q.split(SIP)[-1]
 for i, q in enumerate(self.guilds(ctx).queue.queue, 1)
 ]
 
 await ctx.send("\n".join(queue))
 # except if it is empty
 except HTTPException:
 await ctx.send("No songs in queue.")

class YTDLSource(discord.PCMVolumeTransformer):
 """Creates a youtube_dl audio source with volume control."""
 
 def __init__(self, source, *, data, volume=1):
 super().__init__(source, volume)
 self.data = data
 self.title = data.get("title")
 self.url = data.get("url")
 
 @classmethod
 async def from_url(cls, url, loop):
 """Get source by URL."""
 
 # check if the URL is must be streamed
 if url.startswith(STREAM_INDICATOR_PREFIX):
 stream = True
 else:
 stream = False
 
 # get data from the given URL
 data = await loop.run_in_executor(
 None,
 (lambda:
 ytdl.extract_info(
 url.split(STREAM_INDICATOR_PREFIX)[-1], # remove the prefix from the URL
 download=not stream
 ))
 )
 ##$$$$ fix error somtimes
 # take the first item from the entries if there's any
 if "entries" in data:
 try:
 data = data["entries"][0]
 except Exception as e:
 music_logger.exception(e)
 return None
 
 filepath = data["url"] if stream else ytdl.prepare_filename(data) # source url or download path of the file, depends on the 'stream' parameter
 return cls(discord.FFmpegPCMAudio("C:/Users/Motzumoto/Desktop/AGB/ffmpeg/bin", **ffmpeg_options), data=data) # create and return the source

def setup(bot):
 bot.add_cog(Music(bot))