API Thêm Phụ đề
Giá cả
35 credits cho mỗi yêu cầu
Chi phí cố định bất kể độ dài video hay nội dung phụ đề.
Tổng quan
API Thêm Phụ đề thêm phụ đề/chú thích vào video với các entries có thời gian (phong cách CapCut). Text tự động chia thành nhiều entries dựa trên max_words_per_line và phân bổ đều theo thời lượng video.
Domain: api.revidapi.com
Endpoints
Endpoint Chính
POST https://api.revidapi.com/paid/add-subtitle
Xác thực: Bắt buộc - Header x-api-key
Domain: api.revidapi.com
Endpoint chính để thêm phụ đề với tự động chia text. Text sẽ tự động chia thành các timed entries dựa trên max_words_per_line và phân bổ đều theo thời lượng video.
Endpoint Thay thế: Thêm Phụ đề từ Tệp SRT
POST https://api.revidapi.com/paid/add-subtitle-from-srt
Xác thực: Bắt buộc - Header x-api-key
Domain: api.revidapi.com
Chấp nhận URL tệp SRT trực tiếp. Hữu ích khi bạn đã có tệp SRT được định dạng sẵn với thông tin timing. Xem phần chi tiết bên dưới.
Endpoint Thay thế: Thêm Phụ đề với Timing Chính xác
POST https://api.revidapi.com/paid/add-timed-subtitle
Xác thực: Bắt buộc - Header X-API-Key
Domain: api.revidapi.com
Thêm phụ đề với điều khiển timing chính xác. Yêu cầu mảng timed entries chính xác, cho phép bạn kiểm soát hoàn toàn thời điểm xuất hiện của mỗi phụ đề. Xem phần chi tiết bên dưới.
Yêu cầu
Headers
x-api-key: Bắt buộc. API key của bạn để xác thực.Content-Type: Bắt buộc. Phải làapplication/json.
Tham số Body
Tham số Bắt buộc
| Parameter | Type | Required | Default | Mô tả |
|---|---|---|---|---|
video_url |
string (URI) | ✅ Yes | - | URL của tệp video (thường là video đã blur) |
subtitle_text |
string | ✅ Yes | - | Text phụ đề (sẽ tự động chia thành entries) |
Tham số Tùy chọn
| Parameter | Type | Required | Default | Mô tả |
|---|---|---|---|---|
timed_entries |
array | ❌ No | null |
Danh sách timed entries từ TTS (sync với voice) |
audio_duration |
number | ❌ No | null |
Thời lượng của TTS audio (để sync) |
settings |
object | ❌ No | {} |
Các tùy chọn styling (xem Settings Schema bên dưới) |
webhook_url |
string (URI) | ❌ No | - | URL để nhận kết quả khi xử lý hoàn tất |
id |
string | ❌ No | - | Mã định danh tùy chỉnh để theo dõi yêu cầu |
Settings Schema
{
"text_color": "string (optional)",
"word_color": "string (optional)",
"outline_color": "string (optional)",
"all_caps": "boolean (optional)",
"max_words_per_line": "integer (optional)",
"position_x": "integer (optional)",
"position_y": "integer (optional)",
"position": "string (optional)",
"alignment": "string (optional)",
"font_family": "string (optional)",
"font_size": "integer (optional)",
"bold": "boolean (optional)",
"italic": "boolean (optional)",
"underline": "boolean (optional)",
"strikeout": "boolean (optional)",
"style": "string (optional)",
"outline_width": "integer (optional)",
"spacing": "integer (optional)",
"angle": "integer (optional)",
"shadow_offset": "integer (optional)",
"language": "string (optional)"
}
Tham số Settings
Màu sắc
| Parameter | Type | Default | Mô tả |
|---|---|---|---|
text_color |
string | "#FFFFFF" |
Màu chữ chính (định dạng hex) |
word_color |
string | "#FFFF00" |
Màu highlight (dùng cho karaoke/highlight style) |
outline_color |
string | "#000000" |
Màu viền (định dạng hex) |
outline_width |
integer | 3 |
Độ dày viền (1-10) |
shadow_offset |
integer | 2 |
Độ lệch bóng (0-10) |
Font & Typography
| Parameter | Type | Default | Mô tả |
|---|---|---|---|
font_family |
string | "Be Vietnam Pro" |
Tên font (xem /fonts/{language}) |
font_size |
integer | 48 |
Kích thước font (20-100) |
bold |
boolean | false |
In đậm |
italic |
boolean | false |
In nghiêng |
underline |
boolean | false |
Gạch chân |
strikeout |
boolean | false |
Gạch ngang |
all_caps |
boolean | false |
Chuyển tất cả thành chữ HOA |
spacing |
integer | 0 |
Khoảng cách giữa các ký tự (0-50) |
angle |
integer | 0 |
Góc xoay (độ, -180 đến 180) |
language |
string | "vi" |
Ngôn ngữ (để chọn font phù hợp) |
Vị trí
| Parameter | Type | Default | Mô tả |
|---|---|---|---|
position_x |
integer | null |
Tọa độ X chính xác (center của caption area) |
position_y |
integer | null |
Tọa độ Y chính xác (center của caption area) |
position |
string | null |
Vị trí preset: top_left, top_center, top_right, middle_left, middle_center, middle_right, bottom_left, bottom_center, bottom_right |
alignment |
string | null |
Căn chỉnh text: left, center, right |
⚠️ QUAN TRỌNG:
- Chỉ dùng position_x và position_y (không có alias x, y)
- Lấy từ caption_area của detect-caption để trùng với vị trí blur
- Backend tự động dùng center alignment khi có exact position
Cách tính:
position_x = caption_area.x + caption_area.w / 2
position_y = caption_area.y + caption_area.h / 2
Style Effects
| Parameter | Type | Default | Mô tả |
|---|---|---|---|
style |
string | "classic" |
Style hiệu ứng: classic, karaoke, highlight, underline, word_by_word |
Các tùy chọn Style:
- classic: Hiển thị tất cả text cùng lúc, không animation (phù hợp subtitle thông thường)
- karaoke: Highlight từng từ tuần tự (màu word_color) - giống karaoke
- highlight: Hiển thị full text, highlight từng từ tuần tự (màu word_color)
- underline: Hiển thị full text, gạch chân từng từ tuần tự
- word_by_word: Hiển thị từng từ một (fade in/out)
Bố cục Text
| Parameter | Type | Default | Mô tả |
|---|---|---|---|
max_words_per_line |
integer | 6 |
Số từ tối đa mỗi dòng (3-10) |
Logic Subtitle
Auto-split (Mặc định)
1. Download video
2. Tự động chia text thành entries:
- Mỗi entry: max_words_per_line từ
- Phân bổ đều theo thời lượng video
- Ví dụ: Video 49s, 100 từ → ~2s/entry
3. Tạo ASS file với styling
4. FFmpeg burn subtitle vào video
5. Giữ nguyên audio gốc
Sync với TTS (Khuyến nghị)
Option 1: Dùng timed_entries
{
"video_url": "...",
"subtitle_text": "...",
"timed_entries": [
{"start_time": 0.0, "end_time": 2.5, "text": "Câu đầu tiên"},
{"start_time": 2.5, "end_time": 5.0, "text": "Câu thứ hai"}
]
}
Option 2: Dùng audio_duration
{
"video_url": "...",
"subtitle_text": "...",
"audio_duration": 49.5
}
Option 3: Dùng SRT File (Endpoint riêng)
Sử dụng endpoint /add-subtitle-from-srt với URL tệp SRT.
Endpoint Thay thế: Thêm Phụ đề từ Tệp SRT
Endpoint
POST https://api.revidapi.com/paid/add-subtitle-from-srt
Xác thực: Bắt buộc - Header x-api-key
Endpoint này chấp nhận URL tệp SRT (SubRip Subtitle) trực tiếp. Tệp SRT chứa các timed entries đã được định dạng sẵn, loại bỏ nhu cầu chia text thủ công.
Request Body
Tham số Bắt buộc
| Parameter | Type | Required | Mô tả |
|---|---|---|---|
video_url |
string (URI) | ✅ Yes | URL của tệp video (thường là video đã blur) |
srt_url |
string (URI) | ✅ Yes | URL của tệp SRT phụ đề |
Tham số Tùy chọn
| Parameter | Type | Required | Default | Mô tả |
|---|---|---|---|---|
settings |
object | ❌ No | {} |
Các tùy chọn styling (xem Settings Schema ở trên) |
webhook_url |
string (URI) | ❌ No | - | URL để nhận kết quả khi xử lý hoàn tất |
id |
string | ❌ No | - | Mã định danh tùy chỉnh để theo dõi yêu cầu |
Định dạng Tệp SRT
Tệp SRT nên tuân theo định dạng SubRip chuẩn:
1
00:00:00,000 --> 00:00:02,500
Dòng phụ đề đầu tiên
Dòng phụ đề thứ hai
2
00:00:02,500 --> 00:00:05,000
Mục phụ đề tiếp theo
3
00:00:05,000 --> 00:00:07,500
Mục phụ đề khác
Yêu cầu Định dạng SRT:
- Số thứ tự entries tuần tự
- Định dạng thời gian: HH:MM:SS,mmm --> HH:MM:SS,mmm
- Mỗi entry cách nhau bởi dòng trống
- Text có thể kéo dài nhiều dòng cho mỗi entry
Ví dụ Request
curl -X POST "https://api.revidapi.com/paid/add-subtitle-from-srt" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"srt_url": "https://example.com/subtitles.srt",
"settings": {
"font_family": "Be Vietnam Pro",
"font_size": 48,
"text_color": "#FFFFFF",
"outline_color": "#000000",
"position_x": 288,
"position_y": 688,
"style": "classic"
}
}'
Định dạng Response giống với endpoint chính (trả về task_id, sử dụng GET /paid/get/job/status/{task_id} để kiểm tra trạng thái).
Endpoint Thay thế: Thêm Phụ đề với Timing Chính xác
Endpoint
POST https://api.revidapi.com/paid/add-timed-subtitle
Xác thực: Header X-API-Key hoặc x-api-key
Endpoint này thêm phụ đề với điều khiển timing chính xác. Không giống endpoint chính tự động chia text, endpoint này yêu cầu bạn cung cấp các timed entries chính xác, cho phép kiểm soát hoàn toàn thời điểm xuất hiện của mỗi phụ đề.
Request Body
Tham số Bắt buộc
| Parameter | Type | Required | Mô tả |
|---|---|---|---|
video_url |
string (URI) | ✅ Yes | URL của tệp video (thường là video đã blur) |
subtitles |
array | ✅ Yes | Mảng [{start_time, end_time, text}, ...] |
Tham số Tùy chọn
| Parameter | Type | Required | Default | Mô tả |
|---|---|---|---|---|
settings |
object | ❌ No | {} |
Các tùy chọn styling (xem Settings Schema ở trên) |
webhook_url |
string (URI) | ❌ No | - | URL để nhận kết quả khi xử lý hoàn tất |
id |
string | ❌ No | - | Mã định danh tùy chỉnh để theo dõi yêu cầu |
Định dạng subtitles
[{"start_time": 0.0, "end_time": 2.5, "text": "Đoạn 1"}, {"start_time": 2.5, "end_time": 5.0, "text": "Đoạn 2"}]
Thời gian tính bằng giây (float). start_time < end_time. position_x/position_y lấy từ caption_area của detect.
Ví dụ (payload đã chạy)
{
"video_url": "https://edit.revidapi.com/output/video_xxx.mp4",
"subtitles": [{"start_time": 0.0, "end_time": 2.5, "text": "Đoạn 1"}],
"settings": {
"text_color": "#FFFFFF",
"word_color": "#FFD700",
"outline_color": "#000000",
"all_caps": true,
"font_family": "Montserrat",
"font_size": 38,
"bold": true,
"style": "classic",
"outline_width": 4,
"spacing": 1,
"shadow_offset": 2,
"position_x": 288,
"position_y": 688
}
}
Khi nào sử dụng Endpoint này
Sử dụng /api/add-timed-subtitle khi:
- ✅ Bạn có yêu cầu timing chính xác (ví dụ: từ phần mềm chỉnh sửa video)
- ✅ Bạn muốn đồng bộ phụ đề từng khung hình với audio
- ✅ Bạn có dữ liệu timing phụ đề sẵn có (SRT, VTT, v.v.)
- ✅ Bạn cần kiểm soát hoàn toàn timing của mỗi entry phụ đề
Sử dụng endpoint chính /paid/add-subtitle khi:
- ✅ Bạn chỉ có text và muốn tự động chia
- ✅ Bạn muốn phân bổ text đều theo thời lượng video
- ✅ Bạn có dữ liệu timing TTS nhưng muốn phân bổ tự động
Định dạng Response giống với endpoint chính (trả về task_id, sử dụng GET /api/get/{task_id} để kiểm tra trạng thái trên domain edit.revidapi.com).
Phản hồi
Phản hồi Ngay lập tức (Task Created)
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"status": "pending",
"message": "Task queued",
"type": "subtitle"
}
Trạng thái Task (GET /paid/get/job/status/{task_id})
✅ Hoàn thành
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"type": "subtitle",
"status": "completed",
"progress": 100,
"message": "Added 8 subtitle entries successfully",
"result": {
"video_url": "https://storage.example.com/subtitled_output.mp4",
"entries_count": 8
},
"created_at": "2025-12-22T12:28:01.106964"
}
⏳ Đang xử lý
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"status": "processing",
"progress": 40,
"message": "Created 8 subtitle entries..."
}
❌ Thất bại
{
"task_id": "8ffd7873-3272-4277-a4d2-83fd0c3731b4",
"status": "failed",
"progress": 50,
"message": "FFmpeg error: ..."
}
Ví dụ Yêu cầu
Ví dụ 1: Tối thiểu (Dùng mặc định)
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"subtitle_text": "Đây là text phụ đề sẽ được hiển thị..."
}'
Ví dụ 2: Full Settings với Style
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"subtitle_text": "Đây là text phụ đề...",
"settings": {
"font_family": "Be Vietnam Pro",
"font_size": 48,
"text_color": "#FFFFFF",
"word_color": "#FFFF00",
"outline_color": "#000000",
"outline_width": 3,
"shadow_offset": 2,
"bold": false,
"italic": false,
"underline": false,
"strikeout": false,
"all_caps": false,
"spacing": 0,
"angle": 0,
"position_x": 288,
"position_y": 688,
"max_words_per_line": 6,
"language": "vi",
"style": "highlight"
}
}'
Ví dụ 3: Sync với TTS
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/blurred_video.mp4",
"subtitle_text": "Đây là text phụ đề...",
"audio_duration": 49.5,
"settings": {
"style": "highlight",
"word_color": "#FFFF00"
}
}'
Ví dụ Style
Tham số style điều khiển cách phụ đề được animate và hiển thị. Mỗi style cung cấp hiệu ứng hình ảnh khác nhau để tăng tính dễ đọc và tương tác.
Classic (Mặc định)
Mô tả: Tất cả text xuất hiện cùng lúc với cùng màu. Không có hiệu ứng animation. Tốt nhất cho phụ đề tiêu chuẩn khi khả năng đọc là ưu tiên.
{
"style": "classic",
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3
}
Trường hợp sử dụng: - Phụ đề video tiêu chuẩn - Trình bày chuyên nghiệp - Phim tài liệu - Nội dung giáo dục
Ví dụ cURL:
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/video.mp4",
"subtitle_text": "Chào mừng đến với hướng dẫn của chúng tôi",
"settings": {
"style": "classic",
"text_color": "#FFFFFF",
"font_size": 48
}
}'
Karaoke
Mô tả: Text xuất hiện từng từ một, mỗi từ được highlight tuần tự bằng word_color. Phần còn lại của text giữ nguyên màu text_color. Hoàn hảo cho video kiểu karaoke.
{
"style": "karaoke",
"text_color": "#FFFFFF",
"word_color": "#FFFF00",
"outline_color": "#000000",
"outline_width": 3
}
Trường hợp sử dụng: - Video karaoke - Video lời bài hát - Video đọc tương tác - Nội dung học ngôn ngữ
Ví dụ cURL:
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/song.mp4",
"subtitle_text": "Hát theo lời bài hát",
"settings": {
"style": "karaoke",
"text_color": "#FFFFFF",
"word_color": "#FFD700",
"font_size": 56,
"max_words_per_line": 4
}
}'
Highlight
Mô tả: Tất cả text được hiển thị đồng thời, nhưng các từ được highlight tuần tự bằng word_color. Tạo hiệu ứng hướng dẫn đọc trong khi giữ toàn bộ text hiển thị.
{
"style": "highlight",
"text_color": "#FFFFFF",
"word_color": "#FFFF00",
"outline_color": "#000000",
"outline_width": 3
}
Trường hợp sử dụng: - Video giáo dục trẻ em - Hướng dẫn đọc - Transcript podcast - Hiển thị audiobook
Ví dụ cURL:
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/tutorial.mp4",
"subtitle_text": "Đọc theo từng từ",
"settings": {
"style": "highlight",
"text_color": "#E0E0E0",
"word_color": "#4CAF50",
"font_size": 52
}
}'
Underline
Mô tả: Tất cả text được hiển thị cùng lúc, nhưng các từ được gạch chân tuần tự khi được nói. Cung cấp hướng dẫn đọc tinh tế mà không thay đổi màu text.
{
"style": "underline",
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3
}
Lưu ý: Tham số underline trong settings điều khiển styling gạch chân. Khi dùng style: "underline", animation sẽ tự động gạch chân các từ tuần tự.
Trường hợp sử dụng: - Hướng dẫn đọc tinh tế - Trình bày chuyên nghiệp - Tin tức - Transcript phỏng vấn
Ví dụ cURL:
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/news.mp4",
"subtitle_text": "Tin tức mới nhất",
"settings": {
"style": "underline",
"text_color": "#FFFFFF",
"font_size": 48
}
}'
Word by Word
Mô tả: Chỉ một từ được hiển thị tại một thời điểm với hiệu ứng fade in/out. Tạo trải nghiệm đọc tập trung, tối giản.
{
"style": "word_by_word",
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3
}
Trường hợp sử dụng: - Phong cách video tối giản - Nội dung đọc tập trung - Video thiền/thư giãn - Hướng dẫn tập trung
Ví dụ cURL:
curl -X POST "https://api.revidapi.com/paid/add-subtitle" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://example.com/meditation.mp4",
"subtitle_text": "Tập trung vào từng từ",
"settings": {
"style": "word_by_word",
"text_color": "#FFFFFF",
"font_size": 60,
"bold": true
}
}'
Bảng So sánh Style
| Style | Animation | Hiển thị Tất cả Text | Tốt nhất cho |
|---|---|---|---|
classic |
Không | ✅ Có | Phụ đề tiêu chuẩn |
karaoke |
Highlight từ | ❌ Không (từng từ) | Video nhạc |
highlight |
Highlight từ | ✅ Có | Nội dung giáo dục |
underline |
Gạch chân từ | ✅ Có | Nội dung chuyên nghiệp |
word_by_word |
Fade in/out | ❌ Không (một từ) | Đọc tập trung |
Khuyến nghị Màu theo Style
Karaoke & Highlight:
{
"text_color": "#FFFFFF",
"word_color": "#FFFF00" // Vàng sáng để dễ nhìn
}
Classic & Underline:
{
"text_color": "#FFFFFF",
"outline_color": "#000000",
"outline_width": 3 // Viền đậm để dễ đọc
}
Word by Word:
{
"text_color": "#FFFFFF",
"bold": true, // Làm nổi bật từng từ
"font_size": 60 // Font lớn hơn cho hiển thị một từ
}
Font theo Ngôn ngữ
Tiếng Việt ("vi")
- Be Vietnam Pro ⭐
- Montserrat
- Quicksand
- Nunito
- Roboto
Tiếng Trung ("zh")
- Noto Sans SC
- Noto Sans TC
- WenQuanYi Micro Hei
Tiếng Nhật ("ja")
- Noto Sans JP
- M PLUS Rounded 1c
Tiếng Hàn ("ko")
- Noto Sans KR
- NanumGothic
Xem tất cả: GET /fonts/{language}
Workflow Đầy đủ
1. POST /paid/detect-caption
↓
2. GET /paid/get/job/status/{task_id} (loop)
↓ Lấy caption_area
3. POST /paid/blur-region (dùng caption_area)
↓
4. GET /paid/get/job/status/{task_id} (loop)
↓ Lấy video_url
5. POST /paid/add-subtitle (dùng video_url + caption_area + TTS timing)
↓
6. GET /paid/get/job/status/{task_id} (loop)
↓
7. Download video hoàn chỉnh
Ghi chú Sử dụng
- Giá cố định: Endpoint này tính phí cố định 35 credits cho mỗi yêu cầu, bất kể độ dài video.
- POST trả về ngay với
task_id(không chờ xử lý) - GET task status để lấy kết quả (poll trong loop)
- Text tự động chia thành timed entries (nếu không có
timed_entries) - Vị trí nên dùng
caption_areatừ detect-caption để trùng vị trí blur - Audio gốc được giữ nguyên (copy stream)
- Sync với TTS: Dùng
timed_entrieshoặcaudio_durationđể sync chính xác với voice
Tips
- Text quá dài: Tăng
max_words_per_linelên 8-10 - Phụ đề quá nhỏ: Tăng
font_sizelên 60-72 - Phụ đề lệch vị trí: Dùng
position_xvàposition_ytừcaption_area - Màu không rõ: Tăng
outline_widthlên 4-5 - Sync với voice: Dùng
timed_entriestừ TTS service hoặcaudio_duration - Style karaoke: Dùng
style: "karaoke"vớiword_color: "#FFFF00" - Rotation: Dùng
angle: 45để xoay phụ đề (độ) - Character spacing: Dùng
spacing: 5để tăng khoảng cách giữa các ký tự - All caps: Dùng
all_caps: trueđể chuyển tất cả thành chữ HOA - Vị trí: Chỉ dùng
position_xvàposition_y(không có alias x, y)
Vấn đề Thường gặp
- Định dạng SRT không hợp lệ: Đảm bảo tệp SRT được định dạng đúng với timestamp hợp lệ
- Font không có sẵn: Một số font có thể không có sẵn trên server
- Vị trí bị cắt: Đảm bảo vị trí phụ đề không bị cắt bởi cạnh video
Thực hành Tốt nhất
- Dùng Webhooks: Luôn dùng webhooks để đáng tin cậy hơn
- ID duy nhất: Cung cấp giá trị
idduy nhất để theo dõi - Xác thực SRT: Xác thực định dạng tệp SRT trước khi gửi
- Nhất quán Styling: Dùng styling nhất quán qua các video để trải nghiệm người dùng tốt hơn
- Tương phản Màu: Đảm bảo tương phản đủ giữa text và nền để dễ đọc