Bạn biết tôi qua Upwork? Nếu bạn biết tôi qua Upwork và muốn sử dụng dịch vụ, vui lòng liên hệ qua Upwork. Tin nhắn từ khách Upwork gửi ngoài Upwork sẽ không được trả lời.
So sánh🎬 Phụ đề & Caption

Phụ đề nhúng cứng hay phụ đề mềm cho video mạng xã hội?

Phụ đề nhúng cứng hay phụ đề mềm: TikTok và Reels cần burn-in, YouTube nhận upload SRT. Hai lệnh ffmpeg song song với cài đặt force_style và mov_text chính xác.

Dao Huy (Lucas)7 phút đọc8 phần · bảng đối chiếu
Phụ đề nhúng cứng hay phụ đề mềm cho video mạng xã hội?

💡 Với video mạng xã hội, nền tảng quyết định phương pháp. TikTok và Instagram Reels không nhận file phụ đề bên ngoài, vì vậy phụ đề nhúng cứng là cách duy nhất để có văn bản có style. YouTube và YouTube Shorts nhận upload SRT trực tiếp, nên track phụ đề mềm là lựa chọn tốt hơn: không encode lại, người xem tắt bật được, dùng lại cho nhiều ngôn ngữ.

Ý chính

  • Nhúng cứng: -vf "subtitles=captions.srt:force_style='FontName=Arial,FontSize=28,Outline=2,MarginV=160'" kèm encode lại bằng -c:v libx264 -crf 23. Văn bản trở thành pixel vĩnh viễn.
  • Track mềm (MP4): -c:s mov_text -metadata:s:s:0 language=vie -disposition:s:0 default. Video và âm thanh sao chép bằng -c:v copy -c:a copy: không encode lại, không mất chất lượng.
  • TikTok và Instagram Reels: không có slot upload file phụ đề. Nhúng cứng là cách duy nhất giao nộp phụ đề có style và vị trí chính xác trước khi upload.
  • YouTube và YouTube Shorts: upload SRT hoặc VTT trực tiếp trong YouTube Studio. Không cần export lại video; người xem bật tắt được track.
  • Phụ đề nhúng cứng không đáp ứng WCAG 1.2.2 cho web video (không tắt được). Track mềm là bắt buộc khi có yêu cầu tuân thủ khả năng tiếp cận.

Phụ đề nhúng cứng và phụ đề mềm khác nhau như thế nào?

Phụ đề nhúng cứng (burn-in hoặc hardcoded captions) được render trực tiếp vào khung hình video: mỗi pixel văn bản trở thành một phần của hình ảnh vĩnh viễn. Sau khi encode xong, không thể xóa hay di chuyển chúng. Phải encode lại là điều không thể tránh khỏi vì bộ lọc subtitles chạy trong video filter graph của ffmpeg và yêu cầu video phải được giải mã, lọc rồi nén lại.

Phụ đề mềm nằm trong một track riêng bên trong container. Player render chúng khi phát. Luồng video không bị động đến: -c:v copy truyền nguyên byte qua. Tôi dùng track mềm cho mọi nội dung cần chỉnh sửa sau, giao nộp nhiều ngôn ngữ, hay để người xem tự kiểm soát.

Yếu tốNhúng cứngTrack mềm
Người xem tắt bật đượcKhôngCó (menu phụ đề)
Cần encode lại videoCóKhông (-c:v copy)
Chỉnh sửa được sau khi giaoKhôngCó (thay file phụ đề)
Nhiều ngôn ngữMỗi ngôn ngữ một lần encodeNhiều track, một file video
WCAG 1.2.2 (web)Không đáp ứng (không tắt được)Đáp ứng yêu cầu bật tắt

Những nền tảng mạng xã hội nào chấp nhận upload file phụ đề?

Đây là điểm phân kỳ quyết định toàn bộ quy trình. YouTube là ngoại lệ giúp track mềm khả thi với creator. TikTok và Reels là lý do tại sao burn-in tồn tại như một quy trình creator.

Nền tảngUpload SRTUpload VTTAuto-captionsChỉnh sửa trong app
YouTube / ShortsCóCóCóCó (YouTube Studio)
TikTokKhôngKhôngCóCó (sau auto-gen)
Instagram ReelsKhôngKhôngCóCó (app Edits)

YouTube còn nhận SBV, SCC, TTML và nhiều định dạng khác. Với creator cần giao nộp track phụ đề đã dịch, SRT là lựa chọn đơn giản nhất: văn bản thuần, chỉnh sửa được bằng bất kỳ editor nào.

TikTok và Instagram tự tạo auto-captions từ âm thanh sau khi upload, và đều cho phép chỉnh sửa text trong app. Không nền tảng nào có slot upload file phụ đề bên ngoài. Nếu text tự động sai hoặc cần track ngôn ngữ thứ hai, tùy chọn duy nhất là burn phiên bản đã sửa vào pixel video trước khi upload.

Làm thế nào để burn phụ đề vào video bằng ffmpeg?

Bộ lọc subtitles render SRT, WebVTT hoặc bất kỳ định dạng nào libass hỗ trợ. Tùy chọn force_style ghi đè style libass mặc định bằng tên trường ASS V4+. Đây là lệnh tôi dùng cho video dọc 1080x1920 để đăng lên TikTok hoặc Reels:

ffmpeg -i input.mp4 \
  -vf "subtitles=captions.srt:force_style='FontName=Arial,FontSize=28,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,BorderStyle=1,Outline=2,Shadow=0,MarginV=160'" \
  -c:v libx264 -crf 23 -preset slow \
  -pix_fmt yuv420p \
  -c:a copy \
  burned_output.mp4

Các flag quan trọng:

  • force_style='...': ghi đè style libass mặc định. Màu sắc ASS dùng thứ tự byte ABGR: trắng là &H00FFFFFF, viền đen đặc là &H00000000. Byte alpha 00 = hoàn toàn không trong suốt.
  • MarginV=160: khoảng cách pixel từ mép dưới frame 1080x1920. Tôi giữ ở 160px trên video dọc để văn bản không bị UI phía dưới của TikTok và Reels che khuất.
  • -c:v libx264 -crf 23 -preset slow: encode H.264 ở CRF 23 với preset slow để nén tốt hơn. Dùng -crf 18 nếu cần chất lượng cao hơn.
  • -pix_fmt yuv420p: bắt buộc chroma subsampling 4:2:0. Một số bản build ffmpeg sinh ra yuv420p10 khi libass render; nền tảng sẽ convert lại và làm mờ text thêm một lần nữa.
  • -c:a copy: bộ lọc subtitle không động đến âm thanh. Sao chép nguyên vẹn.

Làm thế nào để thêm track phụ đề mềm mà không encode lại video?

Với output MP4, codec subtitle văn bản duy nhất được chấp nhận là mov_text (3GPP Timed Text). Dùng -c:s srt hoặc -c:s copy vào output MP4 sẽ báo lỗi hoặc ghi track mà hầu hết player âm thầm bỏ qua. Với YouTube, tôi sản xuất MP4 trước, rồi upload file .srt riêng qua YouTube Studio: không encode lại ở bất kỳ bước nào.

ffmpeg -i video.mp4 -i captions.srt \
  -map 0 -map 1 \
  -c:v copy -c:a copy \
  -c:s mov_text \
  -metadata:s:s:0 language=vie \
  -metadata:s:s:0 title="Vietnamese" \
  -disposition:s:0 default \
  soft_output.mp4

Ý nghĩa từng flag:

  • -map 0 -map 1: đưa tất cả stream từ video input, cộng stream đầu tiên từ SRT input.
  • -c:v copy -c:a copy: truyền video và âm thanh nguyên byte. Không mất chất lượng, gần như không tốn thời gian xử lý.
  • -c:s mov_text: chuyển SRT sang định dạng 3GPP Timed Text, codec subtitle văn bản duy nhất MP4 hỗ trợ.
  • -metadata:s:s:0 language=vie: mã ISO 639-2 cho tiếng Việt. Dùng eng cho tiếng Anh, fra cho tiếng Pháp.
  • -disposition:s:0 default: đánh dấu track này là mặc định, player sẽ tự chọn khi phát.

Kiểm tra kết quả: ffprobe -v error -select_streams s -show_entries stream=codec_name:stream_tags=language -of default=noprint_wrappers=1 soft_output.mp4. Nếu codec_name không phải mov_text, hầu hết player sẽ âm thầm bỏ qua track đó.

Có nên kết hợp cả hai phương pháp trên cùng một file không?

Tôi làm điều này khi client cần cả hai: cả độ phủ nền tảng lẫn khả năng tùy chỉnh cho người xem. Quy trình: bắt đầu từ cùng một video nguồn và SRT, sản xuất file MP4 nhúng cứng cho TikTok và Reels, và file MP4 riêng với track mềm cho YouTube. Cả hai output dùng chung timing và text: không có sự phân kỳ giữa các phiên bản.

Trường hợp kết hợp mang lại giá trị rõ nhất là track phụ đề đã dịch. Burn phiên bản tiếng Việt vào bản TikTok (vì TikTok không nhận file sidecar). Nhúng track tiếng Việt mềm vào bản YouTube cạnh track tiếng Anh. Một SRT mỗi ngôn ngữ, hai biến thể giao nộp, không cần dịch lại.

Tự làm được gì và khi nào chuyên gia thực sự cần thiết?

Cả hai lệnh trên hoàn toàn tự làm được. Viết SRT, burn cho TikTok và Reels, upload SRT lên YouTube Studio. Với nội dung một ngôn ngữ và giọng nói rõ ràng, quy trình này bao phủ toàn bộ yêu cầu kỹ thuật.

Bài toán thay đổi khi cần phụ đề đã dịch. Tiếng Việt dịch từ tiếng Anh thường vượt giới hạn tốc độ đọc vì dòng tiếng Việt dài hơn gốc tiếng Anh. File .srt dịch máy được timing theo cue tiếng Anh thường chạy quá nhanh. Tôi dịch trong Subtitle Edit với cảnh báo CPS hiển thị trực tiếp, điều chỉnh ngắt dòng cho đến khi mọi event nằm trong giới hạn tốc độ đọc trước khi đưa vào ffmpeg.

Với series video thương hiệu, giao nộp nhiều ngôn ngữ, hay web video cần đáp ứng style guide, timing chuyên nghiệp và QC ngôn ngữ bản địa xứng đáng với chi phí. Dịch vụ phụ đề dọc của tôi bao gồm cả hướng burn-in lẫn hướng giao nộp track mềm, từ dịch thuật đến export ffmpeg.

Câu hỏi thường gặp

Có thể burn phụ đề mà không encode lại video không?

Không. Bộ lọc subtitles và ass chạy trong video filter graph của ffmpeg, đòi hỏi giải mã và encode lại luồng video. Dùng -c:v copy trong khi có -vf filter sẽ báo lỗi. Âm thanh không bị ảnh hưởng: -c:a copy luôn hoạt động song song với subtitle filter.

Tại sao phụ đề burn-in của tôi bị mờ sau khi upload lên TikTok?

TikTok encode lại mọi video upload. Nếu phụ đề được render lên proxy đã scale xuống trước khi encode H.264 cuối, quá trình upload encode nhân thêm độ mờ. Luôn burn trên frame đầy đủ 1080x1920. Cũng kiểm tra đã thêm -pix_fmt yuv420p chưa: một số bản ffmpeg sinh yuv420p10 khi libass render, và pipeline của TikTok xử lý điều đó với thêm một lần chuyển đổi chroma.

Có thể upload phụ đề tiếng Việt lên YouTube như track mềm không?

Có. Upload file .srt tiếng Việt trong YouTube Studio và chọn ngôn ngữ Vietnamese. Người xem chọn track đó từ menu phụ đề cạnh các track khác. Lưu file ở chế độ UTF-8 không có BOM từ Subtitle Edit: ký tự tiếng Việt đầy đủ dấu nằm trong phạm vi UTF-8 và hiển thị đúng trên player YouTube.

mov_text có giữ nguyên dấu tiếng Việt trong file MP4 không?

Có, miễn là SRT nguồn được encode UTF-8. Codec mov_text lưu text trong UTF-8 bên trong MP4. Trường hợp thất bại thường gặp là file nguồn được lưu dưới Windows-1252: dấu tiếng Việt bị lỗi trước khi ffmpeg xử lý text. Kiểm tra File > Character encoding trong Subtitle Edit và lưu lại dưới UTF-8 không có BOM trước khi chạy lệnh ffmpeg.

Dùng CRF bao nhiêu khi burn phụ đề cho video mạng xã hội?

Với TikTok và Reels, tôi dùng -crf 23: tạo file sạch ở dung lượng hợp lý và nền tảng sẽ encode lại ở phía họ dù sao. Với upload YouTube nơi nền tảng giữ lại nhiều chất lượng hơn, tôi thích -crf 18 để text burn-in sắc nét hơn sau khi platform xử lý. Cả hai dùng -preset slow để nén tốt hơn ở cùng mức chất lượng.

Nguồn

Dao Huy (Lucas)
Dao Huy (Lucas)
Tốt nghiệp Trường Đại học Ngoại ngữ, Đại học Đà Nẵng. Ký cam kết chính xác trên mọi bản dịch có xác nhận (USCIS, IRCC).

Bài viết bởi Đào Huy (Lucas), biên dịch viên và chuyên viên bản địa hóa tiếng Việt (Anh, Trung, Pháp sang Việt). See translation services →

Báo giáWhatsApp