Mọi người đều khác nhau, nhưng tôi tin rằng gần như tất cả chúng ta đều thích nghe nhạc.
Nếu muốn giữ lại phiên bản cục bộ của luồng âm thanh mà bạn thường nghe, bạn cần tải xuống các tệp này. Đôi khi, bạn cũng muốn cắt một phần của tệp âm thanh này thay vì chỉ có sẵn toàn bộ nội dung.
Bạn có thể phát triển tập lệnh Python để thực hiện chính xác những điều này. Bạn cũng có thể mở rộng nó với chức năng bổ sung nếu muốn. Và tôi sẽ chỉ cho bạn cách thực hiện trong hướng dẫn này.
Lưu ý về bản quyền
Nếu bạn đã từng sử dụng Internet, bạn có thể biết rằng vấn đề bản quyền có thể khiến nhiều người khó chịu – ở cả hai phía trong cuộc tranh luận về nội dung miễn phí nên như thế nào.
Chính thư viện mà chúng ta sẽ sử dụng đã có một phần rắc rối về bản quyền.
Rất may, có sẵn tài liệu không có bản quyền để chúng ta vừa thưởng thức vừa chơi trong các chương trình của mình. Vì vậy, chúng tôi sẽ sử dụng phần âm thanh Chương 4 trong Giao hưởng số 9 của Beethoven miễn phí bản quyền trong hướng dẫn này.
Hướng dẫn này giả định rằng bạn cũng sẽ sử dụng các phương pháp sau để tải xuống tài liệu không có bản quyền. Không sử dụng thông tin này để vi phạm bất kỳ bản quyền nào!
Chúng ta sẽ làm gì trong Hướng dẫn này
Trước tiên, chúng ta sẽ cài đặt phần phụ thuộc cơ bản, FFMPEG. Sau đó, chúng tôi sẽ cài đặt youtube-dl
thư viện (cũng hoạt động với Vimeo và nhiều nền tảng khác) để tải xuống âm thanh từ URL YouTube và sử dụng âm thanh đó trên mã Python.
Tiếp theo, chúng tôi sẽ tải xuống pydub
thư viện để cắt các tệp âm thanh và triển khai chức năng này trong mã của chúng tôi.
Cuối cùng, chúng tôi sẽ tạo một số giao diện người dùng thân thiện để chúng tôi có thể sử dụng lại tập lệnh này sau này mà không phải chỉnh sửa mã.
Tất cả điều này sẽ được thực hiện bên trong một main()
chức năng để chúng ta có thể tách biệt chức năng, triển khai và sử dụng.
Cách cài đặt gói FFMPEG
Gói này là cốt lõi của nhiều chương trình đa phương tiện (và tất cả các chương trình nguồn mở mà tôi đã sử dụng cho đến nay). Chúng tôi sẽ cần nó cho cả hai thư viện Python mà chúng tôi sẽ sớm cài đặt.
Cách cài đặt trên Linux
Nếu bạn đang sử dụng máy dựa trên Debian (chẳng hạn như Ubuntu hoặc Kali), đây là lệnh để cài đặt FFMPEG:
sudo apt-get install ffmpeg
Nếu bạn đang sử dụng các loại bản phân phối khác, hướng dẫn cài đặt có tại đây.
Cách cài đặt trên Windows
Đầu tiên, cài đặt Trình quản lý gói Chocolatey. Hướng dẫn cài đặt ở đây, tôi sẽ đợi.
Khi bạn đã cài đặt chocolatey đúng cách (nếu bạn chưa có), hãy tải xuống gói từ phiên bản quản trị của Powershell:
choco install ffmpeg
Cách cài đặt trên máy Mac
Nếu bạn chưa có nó, hãy cài đặt homebrew. Sau đó, trong một thiết bị đầu cuối:
brew install ffmpeg
Cách tải xuống âm thanh theo chương trình từ URL YouTube
Trước hết, hãy tải xuống gói youtube-dl từ pip. Đây là một trong những thứ được gắn sao nhiều nhất trên GitHub.
pip install youtube-dl
Chúng tôi sẽ nhập mô-đun này và sau đó khai báo một chức năng tải xuống âm thanh ở định dạng mp3 với chất lượng hợp lý từ URL YouTube.
import youtube_dl # client to many multimedia portals
# downloads yt_url to the same directory from which the script runs
def download_audio(yt_url):
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([yt_url])
def main():
yt_url = "https://www.youtube.com/watch?v=8OAPLk20epo"
download_audio(yt_url)
main()
Các .download()
phương thức sẽ dần dần tải xuống luồng âm thanh dưới dạng .webm
tập tin. Sau khi phát hiện toàn bộ tệp có sẵn, nó sẽ sử dụng ffmpeg
để chuyển đổi nó thành tệp âm thanh MP3. Điều này có nghĩa là nếu có điều gì đó xảy ra, chẳng hạn như kết nối internet bị ngắt khi tệp được tải xuống 90%, tệp sẽ tiếp tục tải xuống ở mức 90% thay vì tải xuống từ đầu – khá gọn gàng.
Lưu ý rằng nếu bạn đã tải xuống tệp mp3, quá trình tải xuống sẽ khởi động lại và ghi đè lên tệp.
Chạy tập lệnh Python của bạn. Bản tải xuống âm thanh cho phần diễn giải này của Chương 4 trong Bản giao hưởng số 9 của Beethoven phải có tệp MP3 ~33 Mb với tiêu đề của video có sẵn tại địa phương. Có lẽ sẽ hơi chậm, vì vậy hãy đi pha trà cho mình.
Như bạn có thể thấy, có thể chuyển các tham số tùy chọn cho youtube-dl (cũng sẽ có sẵn dưới dạng chương trình CLI độc lập bên ngoài tập lệnh). Một trong những khả năng của nó là tải xuống một loạt video từ URL danh sách phát. Nếu bạn quan tâm hơn, bạn có thể đọc tài liệu của họ. Tôi sẽ tiếp tục sử dụng tầm thường hơn trong hướng dẫn này.
Cách cắt tệp đã tải xuống
Với tệp đã tải xuống, bây giờ chúng tôi sẽ tùy ý cắt nó cục bộ (bạn có thể đã cân nhắc liệu có thể chỉ cần tải xuống một clip từ YouTube hay không. Tất cả các phương pháp đáng tin cậy mà tôi đã tìm thấy về cơ bản sẽ tải xuống toàn bộ và sau đó chỉnh sửa tại địa phương). Để làm được điều đó, chúng tôi sẽ sử dụng thư viện pydub. Bạn có thể cài đặt nó như thế này:
pip install pydub
Đây là một thư viện khá hay cho phép bạn thao tác hoàn toàn với âm thanh, giảm hoặc tăng âm lượng theo các khoảng thời gian nhất định, lặp lại clip, v.v. Hiện tại, chúng tôi chỉ quan tâm đến việc cắt tỉa.
Để cắt tệp đã tải xuống của chúng tôi, chúng tôi sẽ phải lấy tên tệp của MP3 mới tải xuống, chuyển đổi điểm bắt đầu và điểm kết thúc của khoảng thời gian âm thanh mong muốn từ ‘giờ:phút:giây’ thành mili giây và cuối cùng sử dụng pydub
để cắt tập tin âm thanh của chúng tôi.
Cách lấy tên tệp
thật không may .download()
phương thức sẽ không trả lại tên tệp đã tạo của chúng tôi, mà chúng tôi cũng sẽ không có quyền truy cập vì chúng tôi chỉ chuyển URL dưới dạng tham số. Nhưng chúng tôi có Python và đây là một công cụ tuyệt vời.
Chúng tôi biết rằng chúng tôi đang tìm kiếm một .mp3
tệp được tạo ngay trước thao tác tra cứu tên tệp của chúng tôi (Python là tệp đơn luồng và sẽ thực thi mã đồng bộ theo mặc định). Chúng tôi sẽ lấy tên của MP3 gần đây nhất trong thư mục tập lệnh và đó sẽ là tệp của chúng tôi.
Chúng ta có thể thực hiện thao tác này bằng cách liệt kê tất cả .mp3
các tệp trong thư mục cục bộ, thu thập dấu thời gian của chúng dưới dạng số nguyên (có nghĩa là thời gian tính bằng mili giây được tính từ một ngày nhất định trong quá khứ. Điều này có nghĩa là giá trị càng cao thì thời gian tệp được tạo càng xa). giá trị cao nhất.
Đối với điều này, chúng tôi sẽ cần các mô-đun glob
để điều hướng thư mục và os
để lấy thông tin dấu thời gian, cả hai đều có sẵn.
import glob
import os
def newest_mp3_filename():
# lists all mp3s in local directory
list_of_mp3s = glob.glob('./*.mp3')
# returns mp3 with highest timestamp value
return max(list_of_mp3s, key = os.path.getctime)
Cách nhận HH:MM:SS dưới dạng mili giây
Sau khi chúng tôi cắt tệp của mình, pydub
sẽ mong đợi các khoảng thời gian được biểu thị bằng mili giây. Nhưng đối với con người chúng ta, việc tính toán thời điểm chính xác tính bằng mili giây mỗi khi chúng ta muốn cắt video sẽ khá khó chịu, vì vậy chúng ta sẽ trân trọng yêu cầu máy tính làm điều đó cho chúng ta.
Đầu vào của chúng tôi sẽ là một chuỗi trong Giờ:MM:SS định dạng. Điều này hoạt động tốt nếu chúng tôi muốn cắt video dài hơn một giờ, nhưng hầu hết thời gian chúng tôi sẽ chỉ muốn lấy khoảng thời gian từ khoảng thời gian một phút:giây sang khoảng thời gian khác. Vì vậy, chúng ta cũng phải xem xét điều này.
Một mili giây là 1/1000 giây, một phút là 60 giây và một giờ là 60 phút. Vì vậy, chúng ta phải lấy giá trị cho giờ, sau đó là phút, sau đó là giây, thực hiện chuyển đổi mili giây trên mỗi giá trị, sau đó tính tổng các phần để đạt được kết quả.
def get_video_time_in_ms(video_timestamp):
vt_split = video_timestamp.split(":")
if (len(vt_split) == 3): # if in HH:MM:SS format
hours = int(vt_split[0]) * 60 * 60 * 1000
minutes = int(vt_split[1]) * 60 * 1000
seconds = int(vt_split[2]) * 1000
else: # MM:SS format
hours = 0
minutes = int(vt_split[0]) * 60 * 1000
seconds = int(vt_split[1]) * 1000
# time point in miliseconds
return hours + minutes + seconds
Cách lấy âm thanh đã cắt
Bây giờ chúng ta sẽ đọc MP3 dưới dạng pydub
đối tượng và cắt khoảng thời gian mong muốn của chúng tôi. Cú pháp hoàn toàn giống với các thao tác cắt trên chuỗi và mảng, nhưng thay vì chỉ mục cho một phần tử, chúng tôi sẽ sử dụng mili giây cho các thời điểm cụ thể trong âm thanh.
def get_trimmed(mp3_filename, initial, final = ""):
if (not mp3_filename):
# raise an error to immediately halt program execution
raise Exception("No MP3 found in local directory.")
# reads mp3 as a PyDub object
sound = AudioSegment.from_mp3(mp3_filename)
t0 = get_video_time_in_ms(initial)
print("Beginning trimming process for file ", mp3_filename, ".\n")
print("Starting from ", initial, "...")
if (len(final) > 0):
print("...up to ", final, ".\n")
t1 = get_video_time_in_ms(final)
return sound[t0:t1] # t0 up to t1
return sound[t0:] # t0 up to the end
Làm thế nào để kết hợp tất cả lại với nhau
Alle Menschen werden Brüder,
Wo dein sanfter Flügel weilt.
— Friedrich Schiller
Trong trường hợp bạn đang thắc mắc, đoạn trước có nghĩa là “Tất cả đàn ông sẽ trở thành anh em, bất cứ nơi nào đôi cánh dịu dàng của bạn bay lượn”. Đó là một mảnh vỡ của ca ngợi niềm vuimột bài thơ của Friedrich Schiller, được sử dụng như hầu hết lời bài hát cho các phần hợp xướng của Phong trào thứ 4.
Đây là đoạn nổi tiếng nhất của chuyển động nổi tiếng nhất của bản giao hưởng nổi tiếng nhất của Beethoven. Dù bạn là ai, bất cứ khi nào và bạn lớn lên như thế nào, bạn rất có thể nhận ra tác phẩm này.
Bây giờ chúng ta sẽ tập hợp những gì chúng ta đã làm. Chúng tôi sẽ tải xuống âm thanh từ YouTube, cắt ca ngợi niềm vui hợp xướng (từ 9:51
đến 14:04
) và lưu dưới dạng <filename> - TRIM.mp3
.
Nếu bạn đã làm theo đúng hướng dẫn, hãy cập nhật main()
chức năng thực hiện từng bước theo cách sẽ để lại cho bạn bản MP3 đầy đủ và phiên bản được cắt bớt của nó dưới dạng các tệp có sẵn trong thư mục mà bạn sẽ chạy tập lệnh từ đó. Đừng quên chạy main()
chức năng ở cuối tập lệnh.
def main():
yt_url = "https://www.youtube.com/watch?v=8OAPLk20epo"
download_audio(yt_url)
initial = "9:51"
final = "14:04"
filename = newest_mp3_filename()
trimmed_file = get_trimmed(filename, initial, final)
trimmed_filename = "".join([filename.split(".mp3")[0], "- TRIM.mp3"])
print("Process concluded successfully. Saving trimmed file as ", trimmed_filename)
# saves file with newer filename
trimmed_file.export(trimmed_filename, format="mp3")
Cách thêm tương tác người dùng trực tiếp từ CLI
Đối với phần này, chúng ta sẽ cần sys
Mô-đun Python, đọc đầu vào được truyền từ dòng lệnh (trong số những thứ khác). Chúng tôi sẽ chỉ cập nhật các biến trong main()
chức năng đọc đầu vào từ CLI thay vì dữ liệu được mã hóa cứng hiện tại.
ARGV đọc đầu vào tuần tự dưới dạng một mảng, bắt đầu từ chỉ mục 1 (0 đại diện cho tên tập lệnh Python đang chạy). Chúng tôi sẽ thiết lập nó để đọc một URL làm đối số đầu tiên, sau đó (tùy chọn) các phần mở rộng cắt xén ban đầu và cuối cùng.
import sys
def main():
if (not len(sys.argv) > 1):
print("Please insert a multimedia-platform URL supported by youtube-dl as your first argument.")
return
yt_url = sys.argv[1]
download_audio(yt_url)
if (not len(sys.argv > 2)): # exit if no instants as args
return
initial = sys.argv[2]
final = ""
if (sys.argv[3]):
final = sys.argv[3]
filename = newest_mp3_filename()
trimmed_file = get_trimmed(filename, initial, final)
trimmed_filename = "".join([filename.split(".mp3")[0], "- TRIM.mp3"])
print("Process concluded successfully. Saving trimmed file as ", trimmed_filename)
# saves file with newer filename
trimmed_file.export(trimmed_filename, format="mp3")
Chạy tập tin để kiểm tra nó. Hãy nhớ cập nhật tên tập lệnh giống với tên trên máy của bạn.
python ytauddown.py https://www.youtube.com/watch?v=8OAPLk20epo 9:51 14:04
Kịch bản cuối cùng
Đây là phiên bản cuối cùng với mọi thứ được đặt cùng nhau. Lưu ý rằng các nhận xét về các mô-đun chỉ liên quan đến những gì chúng ta đang sử dụng chúng và rằng main()
chức năng đang được gọi ở dòng cuối cùng.
import youtube_dl # client to download from many multimedia portals
import glob # directory operations
import os # interface to os-provided info on files
import sys # interface to command line
from pydub import AudioSegment # only audio operations
def newest_mp3_filename():
# lists all mp3s in local directory
list_of_mp3s = glob.glob('./*.mp3')
# returns mp3 with highest timestamp value
return max(list_of_mp3s, key = os.path.getctime)
def get_video_time_in_ms(video_timestamp):
vt_split = video_timestamp.split(":")
if (len(vt_split) == 3): # if in HH:MM:SS format
hours = int(vt_split[0]) * 60 * 60 * 1000
minutes = int(vt_split[1]) * 60 * 1000
seconds = int(vt_split[2]) * 1000
else: # MM:SS format
hours = 0
minutes = int(vt_split[0]) * 60 * 1000
seconds = int(vt_split[1]) * 1000
# time point in miliseconds
return hours + minutes + seconds
def get_trimmed(mp3_filename, initial, final = ""):
if (not mp3_filename):
# raise an error to immediately halt program execution
raise Exception("No MP3 found in local directory.")
# reads mp3 as a PyDub object
sound = AudioSegment.from_mp3(mp3_filename)
t0 = get_video_time_in_ms(initial)
print("Beginning trimming process for file ", mp3_filename, ".\n")
print("Starting from ", initial, "...")
if (len(final) > 0):
print("...up to ", final, ".\n")
t1 = get_video_time_in_ms(final)
return sound[t0:t1] # t0 up to t1
return sound[t0:] # t0 up to the end
# downloads yt_url to the same directory from which the script runs
def download_audio(yt_url):
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([yt_url])
def main():
if (not len(sys.argv) > 1):
print("Please insert a multimedia-platform URL supported by youtube-dl as your first argument.")
return
yt_url = sys.argv[1]
download_audio(yt_url)
if (not len(sys.argv > 2)): # exit if no instants as args
return
initial = sys.argv[2]
final = ""
if (sys.argv[3]):
final = sys.argv[3]
filename = newest_mp3_filename()
trimmed_file = get_trimmed(filename, initial, final)
trimmed_filename = "".join([filename.split(".mp3")[0], "- TRIM.mp3"])
print("Process concluded successfully. Saving trimmed file as ", trimmed_filename)
# saves file with newer filename
trimmed_file.export(trimmed_filename, format="mp3")
# example usage:
# python ytauddown.py https://www.youtube.com/watch?v=8OAPLk20epo 9:51 14:04
main()
Bài tập gợi ý
- Phát hiện xem đầu vào đầu tiên có phải là một URL hợp lệ hay không. Hãy xem Python RegEx nếu bạn không biết bắt đầu từ đâu.
- Phát hiện xem đầu vào thứ hai và thứ ba có ở định dạng hợp lệ hay không (giờ:phút:giây HOẶC phút:giây).
- Thêm tùy chọn đổi tên tệp MP3 trực tiếp từ CLI. Hãy nhớ rằng các đối số ARGV được thực thi theo thứ tự.
- Tái cấu trúc tập lệnh này để tương tác với chức năng của nó bằng GUI. Có thể là web hoặc ứng dụng cục bộ, tùy bạn chọn.
cân nhắc cuối cùng
Tôi hy vọng bạn sẽ vui vẻ với dự án này và sử dụng nó thật tốt.
Hãy nhớ rằng kiếm sống với tư cách là một nghệ sĩ khá khó khăn, đặc biệt là đối với đa số nếu không có sự hỗ trợ của công ty. Hãy nhớ hỗ trợ các nghệ sĩ có tác phẩm mà bạn yêu thích bất cứ khi nào có thể và cũng nhớ hỗ trợ phần mềm nguồn mở.