Call +1 (SMB)-AI-AGENT to book a meeting with the SeaVoice AI agent.
Available 24/7
Back to Blog
Hướng dẫn toàn diện về chuyển đổi âm thanh: Chuyển đổi tệp âm thanh dễ dàng | Chuỗi công cụ âm thanh
Published: 31 tháng 3, 2024
Guoguo Chen
17 min read

Hướng dẫn toàn diện về chuyển đổi âm thanh: Chuyển đổi tệp âm thanh dễ dàng | Chuỗi công cụ âm thanh

Tìm hiểu về các công cụ chuyển đổi tệp âm thanh, chuyển đổi định dạng âm thanh và phần mềm chuyển đổi âm thanh miễn phí tốt nhất. Chuyển đổi tệp âm thanh dễ dàng với hướng dẫn từng bước của chúng tôi.

Audio Toolbox AI Tools

Giới thiệu về chuyển đổi âm thanh

Trong thế giới âm thanh kỹ thuật số, có nhiều cách để lưu trữ âm thanh của chúng ta. Mỗi cách đều có những tính năng đặc biệt riêng, như làm cho tệp nhỏ hơn hoặc giữ cho âm thanh thực sự rõ ràng. Nhưng tại sao lại có nhiều như vậy? Chà, bởi vì mỗi người có những nhu cầu và sở thích khác nhau. Một số định dạng hoạt động tốt để chia sẻ nhạc trực tuyến, trong khi những định dạng khác lại tốt nhất cho các bản ghi âm trong phòng thu.

Nhưng đôi khi, chúng ta cần thay đổi một loại tệp âm thanh thành một loại khác. Có thể trình phát nhạc của chúng ta chỉ phát một loại tệp, nhưng chúng ta có một bài hát ở định dạng khác. Hoặc có thể chúng ta muốn tiết kiệm dung lượng trên máy tính bằng cách làm cho các tệp lớn nhỏ hơn. Đó là lúc chuyển đổi âm thanh xuất hiện. Hôm nay, hãy cùng khám phá thế giới các định dạng âm thanh và tìm hiểu cách dễ dàng chuyển đổi từ định dạng này sang định dạng khác.

Các định dạng âm thanh phổ biến

MP3, WAV, AAC, FLAC, OGG: Tìm hiểu các định dạng âm thanh phổ biến

Trước khi chúng ta đi sâu vào chi tiết chuyển đổi âm thanh, hãy cùng xem xét kỹ hơn một số định dạng âm thanh phổ biến nhất và nơi bạn có thể gặp chúng:

  • MP3 (MPEG-1 Audio Layer 3): MP3 giống như siêu sao của các định dạng âm thanh. Nó hoàn hảo để chia sẻ và nghe nhạc trực tuyến vì nó làm cho tệp nhỏ hơn mà không làm mất quá nhiều chất lượng. Vì vậy, khi bạn tải một bài hát từ internet, rất có thể nó ở định dạng MP3.

  • WAV (Waveform Audio File Format): WAV là tất cả về việc giữ mọi thứ siêu rõ ràng. Đây là định dạng được sử dụng cho các bản ghi âm chuyên nghiệp vì nó không nén âm thanh, điều đó có nghĩa là nó rất tốt để tạo nhạc trong phòng thu.

  • AAC (Advanced Audio Coding): AAC là định dạng được iTunes và Apple Music sử dụng, vì vậy khi bạn mua một bài hát từ iTunes Store, rất có thể nó ở định dạng AAC. Ngoài ra, đây cũng là định dạng mặc định để ghi âm ghi chú giọng nói trên iPhone.

  • FLAC (Free Lossless Audio Codec): FLAC dành cho những người yêu âm thanh muốn có cả hai thế giới tốt nhất: kích thước tệp nhỏ và chất lượng âm thanh hàng đầu. Nó hoàn hảo để lưu trữ các album yêu thích của bạn hoặc thưởng thức âm nhạc chất lượng cao trên tai nghe sang trọng của bạn.

  • OGG (Ogg Vorbis): OGG có thể không phổ biến bằng các định dạng khác, nhưng nó vẫn khá tuyệt. Đây là một định dạng mã nguồn mở rất tốt để phát trực tuyến nhạc trực tuyến. Ngoài ra, nó nhỏ hơn các tệp MP3 và hỗ trợ các tính năng bổ sung như siêu dữ liệu, điều này rất tiện lợi để sắp xếp thư viện nhạc của bạn.

Cách chuyển đổi tệp âm thanh - Các tùy chọn để chuyển đổi âm thanh

Chuyển đổi âm thanh bằng dòng lệnh

Có nhiều tùy chọn để chuyển đổi âm thanh. Nếu bạn thích giao diện GUI, bạn có thể sử dụng các công cụ chuyển đổi âm thanh trực tuyến hoặc Audacity. Nếu bạn sẵn sàng tự mình thực hiện và không ngại gõ, bạn có thể sử dụng SoX hoặc GStreamer, cung cấp nhiều sự linh hoạt hơn. Ở đây, tôi sẽ tập trung vào GStreamer vì nó hỗ trợ cả dòng lệnh và lập trình tốt và tự nhiên hỗ trợ phát trực tuyến (hoặc chuyển đổi nhanh).

Cài đặt GStreamer

Trang web chính thức của GStreamer cung cấp hướng dẫn cài đặt chi tiết cho các hệ điều hành khác nhau, xem tại đây. Các bước sau đây cũng hoạt động.

Đối với các hệ thống Linux, bạn thường có thể sử dụng các trình quản lý gói. Ví dụ, đối với các hệ thống dựa trên Debian/Ubuntu, bạn chỉ cần thực hiện

sudo apt install gstreamer1.0
sudo apt install gstreamer1.0-plugins-base
sudo apt install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly

Hai lệnh thứ hai và thứ ba là tùy chọn nhưng tôi luôn thấy hữu ích khi cài đặt các plugin bổ sung này.

Đối với MacOS, bạn có thể cài đặt thông qua Homebrew. Tương tự như các lệnh Linux, bạn thực hiện

brew install gstreamer

Homebrew không cung cấp các gói riêng biệt cho các plugin Gstreamer “good”, “bad” và “ugly” như đối với các bản phân phối Linux. Thay vào đó, Homebrew thường cài đặt một bộ plugin như một phần của gói gstreamer.

Đối với Windows, có các trình cài đặt được biên dịch sẵn, hãy truy cập tài liệu GStreamer tại đây và làm theo hướng dẫn.

Chuyển đổi âm thanh

Sau khi bạn đã cài đặt GStreamer, việc chuyển đổi từ định dạng âm thanh này sang định dạng khác khá đơn giản. Giả sử bạn có một tệp âm thanh ở định dạng MP3, hãy đặt tên là input.mp3, và bạn muốn chuyển đổi nó sang định dạng WAV, hãy đặt tên là output.wav, bạn chỉ cần chạy lệnh sau:

gst-launch-1.0 filesrc location=input.mp3 ! decodebin ! audioconvert ! audioresample ! wavenc ! filesink location=output.wav

Lệnh này sử dụng các phần tử GStreamer sau:

  • filesrc: Đọc dữ liệu từ một tệp.
  • decodebin: Tự động phát hiện và giải mã định dạng âm thanh của tệp đầu vào.
  • audioconvert: Chuyển đổi định dạng âm thanh sang định dạng phù hợp để chuyển đổi.
  • audioresample: Lấy mẫu lại âm thanh theo tốc độ mẫu mong muốn, nếu cần.
  • wavenc: Mã hóa dữ liệu âm thanh sang định dạng WAV.
  • filesink: Ghi dữ liệu âm thanh đầu ra vào một tệp.

Khi bạn chạy lệnh này, GStreamer sẽ đọc tệp MP3 đầu vào, giải mã nó, chuyển đổi nó sang định dạng WAV và lưu tệp WAV kết quả vào vị trí đã chỉ định.

Bạn có thể chỉ định chi tiết định dạng WAV bằng cách sử dụng phần tử audioconvert. Đây là một ví dụ đặt tốc độ mẫu là 44100 Hz và kênh là âm thanh nổi:

gst-launch-1.0 filesrc location=input.mp3 ! decodebin ! audioconvert ! audio/x-raw,format=S16LE,rate=44100,channels=2 ! wavenc ! filesink location=output.wav

Tương tự, bạn có thể chuyển đổi từ loại này sang loại khác bằng cách sử dụng các plugin GStreamer khác nhau.

Chuyển đổi âm thanh nhanh chóng

Chuyển đổi âm thanh nhanh chóng, hay chuyển đổi âm thanh thời gian thực, là điều cần thiết trong nhiều kịch bản xử lý âm thanh khác nhau. Chỉ cần kể tên một vài:

  • Khả năng thích ứng phát trực tuyến: Khi phát trực tuyến nội dung âm thanh qua mạng, các thiết bị và nền tảng khác nhau có thể có các yêu cầu khác nhau về định dạng và codec âm thanh. Chuyển đổi thời gian thực đảm bảo khả năng thích ứng phát trực tuyến liền mạch bằng cách điều chỉnh động dữ liệu âm thanh để phù hợp với thông số kỹ thuật của từng thiết bị hoặc nền tảng nhận. Khả năng thích ứng này là điều cần thiết để đảm bảo phát lại mượt mà trên các môi trường đa dạng mà không cần xử lý trước hoặc mã hóa lại.
  • Truyền tải độ trễ thấp: Trong các ứng dụng tương tác như giao tiếp bằng giọng nói, trò chơi trực tuyến hoặc sự kiện trực tiếp, việc giảm thiểu độ trễ là rất quan trọng để duy trì khả năng phản hồi thời gian thực và sự tương tác của người dùng. Thực hiện chuyển đổi âm thanh nhanh chóng cho phép dữ liệu âm thanh được truyền với độ trễ tối thiểu, đảm bảo phân phối và phát lại gần như tức thì. Truyền tải độ trễ thấp này nâng cao trải nghiệm người dùng tổng thể, đặc biệt trong các ứng dụng nhạy cảm về thời gian, nơi khả năng phản hồi là tối quan trọng.
  • Hiệu quả tài nguyên: Chuyển đổi âm thanh thời gian thực bảo tồn tài nguyên hệ thống bằng cách tránh nhu cầu lưu trữ hoặc xử lý các tệp âm thanh lớn trước. Thay vì chuyển đổi trước nội dung âm thanh sang các định dạng khác nhau, chuyển đổi nhanh chóng cho phép phân bổ tài nguyên động khi cần, giảm yêu cầu lưu trữ và chi phí xử lý. Cách tiếp cận hiệu quả tài nguyên này đặc biệt có lợi trong các môi trường hạn chế tài nguyên, chẳng hạn như hệ thống nhúng hoặc thiết bị di động, nơi tối ưu hóa việc sử dụng tài nguyên là điều cần thiết để duy trì hiệu suất và khả năng mở rộng.

Trong trường hợp sử dụng cụ thể của chúng tôi, chúng tôi có một phần mềm thông minh đàm thoại có tên SeaMeet chấp nhận các tệp âm thanh hoặc luồng (ví dụ: Google Meet) ở nhiều định dạng âm thanh khác nhau và chuyển đổi cuộc trò chuyện từ giọng nói thành văn bản. Vì vậy, chúng tôi phải chuyển đổi âm thanh ở nhiều định dạng khác nhau thành một định dạng hoạt động với công cụ nhận dạng giọng nói của chúng tôi ngay lập tức.

Chuyển đổi âm thanh nhanh chóng hoặc thời gian thực có thể đạt được bằng cách sử dụng thư viện GStreamer. Tương tự như lệnh, chúng ta sẽ phải tổ chức các plugin GStreamer trong một đường ống chuyển đổi luồng, nhưng lần này, với một ngôn ngữ lập trình.

Hãy cùng đăng một ví dụ hoạt động bằng Python, và chúng ta sẽ giải thích cách nó hoạt động.

#!/usr/bin/python3

import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
import threading
import queue
import time

# Initialize GStreamer
Gst.init(None)

class AudioConverter:
    """
    Converts different audio to PCM in real-time or faster, depending on options.

    Attributes:
        pipeline (Gst.Pipeline): The GStreamer pipeline for processing audio.
        appsrc (Gst.Element): The appsink element for feeding data to the pipeline.
        decodebin (Gst.Element): The decodebin element for decoding different audio.
        audioconvert (Gst.Element): The audioconvert element for format conversion.
        audioresample (Gst.Element): The audioresample element for adjusting sample rate (optional).
        outputformat (Gst.Element): The outputformat element to set output format.
        appsink (Gst.Element): The appsink element for receiving converted data.
        input_queue (queue.Queue): Queue for input audio data chunks.
        output_queue (queue.Queue): Queue for output PCM data chunks.
        thread (threading.Thread): Thread for reading input data and running pipeline.
        options (dict): Dictionary containing configuration options.

    Options:
        sync (bool, default=True): Whether to synchronize appsink with pipeline clock (real-time processing).
        preroll (bool, default=False): Preroll the pipeline before processing data.

    Methods:
        push_data(data_chunk): Pushes an audio data chunk to the input queue.
        pull_converted_data(): Retrieves a converted PCM data chunk from the output queue.
        run(): Starts the pipeline and data processing thread.
        on_pad_added(element, pad): Connects elements in the pipeline.
        new_sample_callback(appsink): Receives newly converted data and adds it to the output queue.
        on_message(bus, message): Handles pipeline messages (EOS, error).
    """

    def __init__(self, options=None):
        """
        Initializes the AudioConverter with default or provided options.
        """
        self.options = options or {}

        # Set default values for all options
        self.options.setdefault("sync", True)
        self.options.setdefault("preroll", False)
        self.options.setdefault("output_format", "audio/x-raw,format=S16LE,rate=16000,channels=1")

        self.pipeline = Gst.Pipeline()

        self.appsrc = Gst.ElementFactory.make("appsrc", "appsrc")
        self.decodebin = Gst.ElementFactory.make("decodebin", "decodebin")
        self.audioconvert = Gst.ElementFactory.make("audioconvert", "audioconvert")
        self.audioresample = Gst.ElementFactory.make("audioresample", "audioresample")
        self.outputformat = Gst.ElementFactory.make("capsfilter", "outputformat")
        self.outputformatcaps = Gst.Caps.from_string(self.options["output_format"])
        self.outputformat.set_property("caps", self.outputformatcaps)
        self.appsink = Gst.ElementFactory.make("appsink", "appsink")

        # Add elements to the pipeline
        self.pipeline.add(self.appsrc)
        self.pipeline.add(self.decodebin)
        self.pipeline.add(self.audioconvert)
        self.pipeline.add(self.audioresample)
        self.pipeline.add(self.outputformat)
        self.pipeline.add(self.appsink)

        # Link elements together
        self.appsrc.link(self.decodebin)
        self.decodebin.connect("pad-added", self.on_pad_added)
        self.audioconvert.link(self.audioresample)
        self.audioresample.link(self.outputformat)
        self.outputformat.link(self.appsink)

        # Set appsink properties
        self.appsink.set_property("emit-signals", True)
        self.appsink.connect("new-sample", self.new_sample_callback)
        if not self.options["sync"]:
            self.appsink.set_property("sync", False)

        # Create input and output queues based on options
        self.input_queue = queue.Queue()
        self.output_queue = queue.Queue()

        self.thread = threading.Thread(target=self.run)
        self.thread.start()

    def push_data(self, data_chunk):
        self.input_queue.put(data_chunk)

    def pull_converted_data(self):
        if not self.output_queue.empty():
            return self.output_queue.get(block=False)  # Wait for data or None
        else:
            return None

    def run(self):
        """
        Starts the pipeline and data processing thread.
        """

        self.pipeline.set_state(Gst.State.PLAYING)
        bus = self.pipeline.get_bus()
        bus.add_signal_watch()
        bus.connect("message", self.on_message)

        # Preroll pipeline if enabled
        if self.options["preroll"]:
            while True:
                msg = bus.timed_pop(Gst.MessageType.ELEMENT, Gst.CLOCK_TIME_NONE)
                if msg is not None:
                    break
            self.pipeline.set_state(Gst.State.NULL)

        while True:
            while self.input_queue.empty():  # Wait for data if the queue is empty
                time.sleep(0.01)

            data_chunk = self.input_queue.get(block=False)  # Wait for data or None
            if data_chunk is None:
                self.appsrc.emit("end-of-stream")
                break  # End of data received

            self.process_data(data_chunk)

        # Wait for the EOS message
        bus.poll(Gst.MessageType.EOS | Gst.MessageType.ERROR, Gst.CLOCK_TIME_NONE)
        self.pipeline.set_state(Gst.State.NULL)

    def process_data(self, data_chunk):
        if data_chunk is None:
            return False

        self.appsrc.emit("push-buffer", Gst.Buffer.new_wrapped(data_chunk))
        return True

    def on_pad_added(self, element, pad):
        if pad.query_caps(None).to_string().startswith("audio/"):
            pad.link(self.audioconvert.get_static_pad("sink"))

    def new_sample_callback(self, appsink):
        sample = appsink.emit("pull-sample")
        if sample:
            buffer = sample.get_buffer()
            data_chunk = buffer.extract_dup(0, buffer.get_size())
            self.output_queue.put(data_chunk)
            print("Data Converted")

        return Gst.FlowReturn.OK

    def on_message(self, bus, message):
        t = message.type
        if t == Gst.MessageType.EOS:
            print("End of stream")
            self.output_queue.put(None)  # Signal end of stream to downstream
            self.pipeline.set_state(Gst.State.NULL)
        elif t == Gst.MessageType.ERROR:
            err, debug = message.parse_error()
            print("Error: %s" % err, debug)
            self.pipeline.set_state(Gst.State.NULL)

    def pipeline_reached_eos(self):
        """
Checks if the pipeline has reached EOS.
"""
        return not self.pipeline or self.pipeline.get_state(Gst.CLOCK_TIME_NONE)[1] == Gst.State.NULL

def main():
    # Create an AudioConverter instance
    converter = AudioConverter(options={"sync": False,
        "output_format": "audio/x-raw,format=S16LE,rate=16000,channels=1"})

    CHUNK_SIZE = 1024  # Adjust as needed
    with open("input.mp3", "rb") as infile, \
         open("output.pcm", "wb") as outfile:

        while True:
            # Read a chunk of data from the input file
            data_chunk = infile.read(CHUNK_SIZE)
            if not data_chunk:
                converter.push_data(None)    # Push stream end.
                break

            # Push the data chunk to the converter
            print("Data Push")
            converter.push_data(data_chunk)

            # Attempt to pull any converted data immediately
            converted_chunk = converter.pull_converted_data()
            while converted_chunk is not None:
                outfile.write(converted_chunk)
                converted_chunk = converter.pull_converted_data()

            # Calculate sleep time based on processed audio duration
            audio_duration = 0.05
            time.sleep(audio_duration)

        # Flush out the remaining data from the pipeline.
        while not converter.pipeline_reached_eos():
            converted_chunk = converter.pull_converted_data()
            while converted_chunk is not None:
                outfile.write(converted_chunk)
                converted_chunk = converter.pull_converted_data()
            # time.sleep(0.01)
        converted_chunk = converter.pull_converted_data()
        if converted_chunk is not None:
            outfile.write(converted_chunk)

        # Flush any remaining data to the output file
        outfile.flush()


    # Signal end of input data and wait for completion
    converter.thread.join()

if __name__ == "__main__":
    main()

Lớp “AudioConverter”

Lớp AudioConverter là chức năng cốt lõi để chuyển đổi định dạng âm thanh theo thời gian thực trong mã này. Hãy cùng phân tích cách nó sử dụng đường ống GStreamer để đạt được điều này.

Các plugin GStreamer chính và luồng dữ liệu như sau:

  1. Các khối dữ liệu âm thanh được đẩy từ chương trình Python đến appsrc.
  2. appsrc đưa dữ liệu vào đường ống.
  3. decodebin giải mã định dạng âm thanh đến.
  4. audioconvert thực hiện chuyển đổi định dạng sang PCM.
  5. audioresample (nếu được bật) điều chỉnh tốc độ mẫu.
  6. outputformat đảm bảo dữ liệu khớp với định dạng PCM mong muốn.
  7. appsink nhận dữ liệu PCM đã chuyển đổi và cung cấp cơ chế gọi lại để chương trình Python truy cập dữ liệu đó.

Nói cách khác, nó chấp nhận dữ liệu âm thanh từng khối bằng cách sử dụng appsrc, chuyển đổi dữ liệu âm thanh và sau đó gửi dữ liệu ra từng khối bằng cách sử dụng appsink.

Một số phương thức chính cho lớp AudioConverter là:

  • on_pad_added: Hàm gọi lại này được kích hoạt khi một pad mới (điểm kết nối dữ liệu) có sẵn trên một phần tử. Nó đặc biệt kiểm tra một pad từ decodebin và liên kết nó với audioconvert để xử lý dữ liệu âm thanh đã giải mã.
  • new_sample_callback: Hàm này được appsink gọi bất cứ khi nào có một mẫu mới (khối dữ liệu PCM đã chuyển đổi) có sẵn. Nó trích xuất dữ liệu từ bộ đệm mẫu và thêm nó vào hàng đợi đầu ra để chương trình Python truy cập.
  • on_message: Hàm này xử lý các thông báo GStreamer nhận được trên bus của đường ống. Nó lắng nghe các thông báo như End-of-Stream (EOS) hoặc lỗi. Khi nhận được EOS, nó báo hiệu kết thúc cho chương trình và dọn dẹp đường ống. Các lỗi được ghi lại để phục vụ mục đích gỡ lỗi.

Lớp AudioConverter tận dụng các chức năng đường ống và phần tử của GStreamer để đạt được chuyển đổi định dạng âm thanh theo thời gian thực. Các phần tử GStreamer xử lý việc giải mã, chuyển đổi và đóng gói dữ liệu âm thanh, trong khi lớp cung cấp các phương thức để tương tác và trao đổi dữ liệu với chương trình Python.

Hàm “main”

Hàm main mô phỏng việc phát trực tuyến âm thanh theo thời gian thực và minh họa cách sử dụng lớp AudioConverter. Bạn có thể viết hàm bao bọc riêng cho lớp AudioConverter nhưng có một vài điểm chính:

Xử lý dựa trên khối

Không giống như việc đọc toàn bộ tệp âm thanh cùng một lúc, mã này đọc dữ liệu theo các khối nhỏ hơn (CHUNK_SIZE). Điều này mô phỏng cách dữ liệu âm thanh có thể được nhận trong một luồng liên tục qua mạng hoặc từ một nguồn trực tiếp.

Truy xuất dữ liệu không chặn

Sau khi đẩy một khối đầu vào, mã cố gắng kéo dữ liệu đã chuyển đổi có sẵn ngay lập tức bằng cách sử dụng pull_converted_data. Điều này mô phỏng cách một ứng dụng phát trực tuyến có thể cần xử lý và có thể phát lại âm thanh đã chuyển đổi càng sớm càng tốt, mà không cần đợi toàn bộ tệp được chuyển đổi.

Ngủ để có thể bắt kịp

Thời gian ngủ được tính toán, mặc dù có thể không hoàn hảo, nhưng tạo ra độ trễ giữa việc đẩy dữ liệu mới và cố gắng kéo dữ liệu đã chuyển đổi. Điều này mô phỏng thời gian tiềm năng mà bộ chuyển đổi (đường ống GStreamer) có thể mất để xử lý khối đã nhận. Nó cho phép bộ chuyển đổi một thời gian để bắt kịp trước khi cung cấp thêm dữ liệu.

Tại sao phải tự mình làm tất cả?

Trong khi việc chuyển đổi tệp âm thanh sang các định dạng khác nhau là cần thiết, tại sao lại dừng lại ở đó? Nâng cao trải nghiệm âm thanh của bạn với SeaMeet.

SeaMeet cung cấp bản ghi và tóm tắt chính xác, theo thời gian thực cho mọi nhu cầu âm thanh của bạn. Cho dù bạn đang chuyển đổi tệp âm thanh, ghi podcast hay chỉ muốn có bản ghi cuộc trò chuyện, SeaMeet cung cấp bản ghi chất lượng cao tức thì và tóm tắt sâu sắc. Công cụ mạnh mẽ này có thể giúp bạn tiết kiệm hàng giờ làm việc thủ công và giúp bạn trích xuất giá trị tối đa từ nội dung âm thanh của mình.

Đăng ký SeaMeet ngay hôm nay và trải nghiệm niềm vui theo dõi cuộc trò chuyện của bạn.

Thêm từ Chuỗi công cụ âm thanh

Related Articles

Ready to Transform Your Customer Communications?

See how Seasalt.ai can help your business automate support, capture leads, and deliver exceptional customer experiences.

Any questions? We follow up with every message.