13 KiB
13 KiB
EasyStream API Quick Start Guide
Get Started in 5 Minutes
This guide will get you up and running with the EasyStream API quickly.
Prerequisites
- EasyStream installed and running
- Modern web browser
- Basic JavaScript knowledge
1. Authentication
Login and Get Token
// The API client is automatically available as 'api'
const result = await api.login('myusername', 'mypassword');
if (result.success) {
console.log('Logged in!');
console.log('User:', result.user);
console.log('Token:', result.token);
// Token is automatically stored
}
Check if Logged In
if (api.isAuthenticated()) {
console.log('User is logged in');
} else {
console.log('Please log in');
}
2. Working with Videos
List Videos
const videos = await api.getVideos({
page: 1,
limit: 20,
sort: 'popular'
});
console.log('Videos:', videos.data.videos);
Get Single Video
const video = await api.getVideo('123456');
console.log('Video:', video.data);
Search Videos
const results = await api.searchVideos('funny cats');
console.log('Found:', results.data.videos);
Like a Video
await api.likeVideo('123456', 'like');
console.log('Video liked!');
Create a Video
const newVideo = await api.createVideo({
title: 'My Awesome Video',
description: 'This is a great video',
privacy: 'public',
category: 'entertainment'
});
console.log('Created video:', newVideo.data.file_key);
3. User Profiles
Get Current User Profile
const myProfile = await api.getMyProfile();
console.log('My profile:', myProfile.data);
Get Another User's Profile
const userProfile = await api.getUserProfile(123);
console.log('User:', userProfile.data);
Update Profile
await api.updateProfile({
usr_dname: 'My New Name',
usr_about: 'I love making videos!'
});
console.log('Profile updated!');
Upload Avatar
<input type="file" id="avatar-input" accept="image/*">
<button onclick="uploadAvatar()">Upload</button>
<script>
async function uploadAvatar() {
const fileInput = document.getElementById('avatar-input');
const file = fileInput.files[0];
if (file) {
const result = await api.uploadAvatar(file);
console.log('Avatar uploaded:', result.data.avatar_url);
}
}
</script>
4. Comments
Get Comments for a Video
const comments = await api.getComments('123456', {
page: 1,
sort: 'recent'
});
console.log('Comments:', comments.data.comments);
Post a Comment
const newComment = await api.createComment(
'123456', // video file_key
'Great video!', // comment text
null // parent_id (null for top-level)
);
console.log('Comment posted:', newComment.data);
Reply to a Comment
const reply = await api.createComment(
'123456', // video file_key
'Thanks!', // reply text
789 // parent comment ID
);
console.log('Reply posted:', reply.data);
5. Subscriptions
Subscribe to a Channel
await api.subscribe(456); // channel user ID
console.log('Subscribed!');
Check if Subscribed
const status = await api.checkSubscription(456);
if (status.data.is_subscribed) {
console.log('Already subscribed');
} else {
console.log('Not subscribed');
}
Get Subscription Feed
const feed = await api.getSubscriptionFeed({ page: 1 });
console.log('New videos from subscriptions:', feed.data.videos);
6. Complete Examples
Video Player Page
<!DOCTYPE html>
<html>
<head>
<title>Watch Video</title>
<style>
.video-container { max-width: 800px; margin: 0 auto; }
.actions button { margin: 5px; }
.comments { margin-top: 20px; }
</style>
</head>
<body>
<div class="video-container">
<h1 id="video-title"></h1>
<p id="video-description"></p>
<div class="actions">
<button id="like-btn">👍 Like</button>
<button id="subscribe-btn">Subscribe</button>
<button id="watch-later-btn">⏰ Watch Later</button>
</div>
<div class="comments">
<h2>Comments</h2>
<div id="comments-list"></div>
<form id="comment-form">
<textarea id="comment-text" placeholder="Add a comment..." required></textarea>
<button type="submit">Post Comment</button>
</form>
</div>
</div>
<script src="/f_scripts/fe/js/api-helper.js"></script>
<script>
const fileKey = '123456'; // Get from URL
// Load video and comments
async function init() {
try {
// Load video
const video = await api.getVideo(fileKey);
document.getElementById('video-title').textContent = video.data.file_title;
document.getElementById('video-description').textContent = video.data.file_description;
// Record view
await api.recordVideoView(fileKey);
// Load comments
await loadComments();
// Setup buttons
setupButtons(video.data);
} catch (error) {
api.handleError(error);
}
}
async function loadComments() {
const comments = await api.getComments(fileKey);
const list = document.getElementById('comments-list');
list.innerHTML = comments.data.comments.map(c => `
<div class="comment">
<strong>${c.usr_dname}</strong>
<p>${c.comment_text}</p>
<small>${c.comment_date}</small>
</div>
`).join('');
}
function setupButtons(video) {
// Like button
document.getElementById('like-btn').addEventListener('click', async () => {
await api.likeVideo(fileKey, 'like');
alert('Video liked!');
});
// Subscribe button
document.getElementById('subscribe-btn').addEventListener('click', async () => {
await api.subscribe(video.usr_id);
alert('Subscribed!');
});
// Watch later button
document.getElementById('watch-later-btn').addEventListener('click', async () => {
await api.toggleWatchLater(fileKey);
alert('Added to Watch Later!');
});
// Comment form
document.getElementById('comment-form').addEventListener('submit', async (e) => {
e.preventDefault();
const text = document.getElementById('comment-text').value;
await api.createComment(fileKey, text);
document.getElementById('comment-text').value = '';
await loadComments();
});
}
// Start
init();
</script>
</body>
</html>
Browse Videos Page
<!DOCTYPE html>
<html>
<head>
<title>Browse Videos</title>
<style>
.video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
.video-card { border: 1px solid #ddd; padding: 15px; }
.filters { margin-bottom: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>Browse Videos</h1>
<div class="filters">
<select id="sort-select">
<option value="recent">Recent</option>
<option value="popular">Popular</option>
<option value="featured">Featured</option>
</select>
<input type="text" id="search-input" placeholder="Search videos...">
<button id="search-btn">Search</button>
</div>
<div class="video-grid" id="video-grid"></div>
<button id="load-more">Load More</button>
</div>
<script src="/f_scripts/fe/js/api-helper.js"></script>
<script>
let currentPage = 1;
let currentSort = 'recent';
let searchQuery = '';
async function loadVideos(append = false) {
try {
let result;
if (searchQuery) {
result = await api.searchVideos(searchQuery, {
page: currentPage,
limit: 20
});
} else {
result = await api.getVideos({
page: currentPage,
limit: 20,
sort: currentSort
});
}
displayVideos(result.data.videos, append);
// Show/hide load more button
const loadMoreBtn = document.getElementById('load-more');
if (currentPage >= result.data.pagination.pages) {
loadMoreBtn.style.display = 'none';
} else {
loadMoreBtn.style.display = 'block';
}
} catch (error) {
api.handleError(error);
}
}
function displayVideos(videos, append = false) {
const grid = document.getElementById('video-grid');
if (!append) {
grid.innerHTML = '';
}
videos.forEach(video => {
const card = document.createElement('div');
card.className = 'video-card';
card.innerHTML = `
<h3>${video.file_title}</h3>
<p>${video.file_description}</p>
<p>
<small>
By ${video.usr_dname} •
${video.file_views} views •
${video.like_count} likes
</small>
</p>
<button onclick="watchVideo('${video.file_key}')">
Watch
</button>
`;
grid.appendChild(card);
});
}
window.watchVideo = function(fileKey) {
window.location.href = `/watch.php?v=${fileKey}`;
};
// Sort change
document.getElementById('sort-select').addEventListener('change', (e) => {
currentSort = e.target.value;
currentPage = 1;
loadVideos(false);
});
// Search
document.getElementById('search-btn').addEventListener('click', () => {
searchQuery = document.getElementById('search-input').value;
currentPage = 1;
loadVideos(false);
});
// Load more
document.getElementById('load-more').addEventListener('click', () => {
currentPage++;
loadVideos(true);
});
// Initial load
loadVideos();
</script>
</body>
</html>
7. Error Handling
Always wrap API calls in try-catch:
try {
const result = await api.someAPICall();
// Handle success
} catch (error) {
// Handle error
console.error('Error:', error.message);
// Use built-in error handler
api.handleError(error);
// Or custom handling
if (error.message.includes('Authentication')) {
window.location.href = '/signin';
} else {
alert('Error: ' + error.message);
}
}
8. Common Patterns
Loading State
async function loadData() {
showLoading(); // Your loading function
try {
const result = await api.getVideos();
displayData(result.data);
} catch (error) {
api.handleError(error);
} finally {
hideLoading(); // Always hide loading
}
}
Infinite Scroll
let currentPage = 1;
let loading = false;
window.addEventListener('scroll', async () => {
if (loading) return;
const scrolledToBottom =
window.innerHeight + window.scrollY >= document.body.offsetHeight - 500;
if (scrolledToBottom) {
loading = true;
currentPage++;
try {
const result = await api.getVideos({ page: currentPage });
appendVideos(result.data.videos);
} catch (error) {
api.handleError(error);
} finally {
loading = false;
}
}
});
Debounced Search
let searchTimeout;
document.getElementById('search-input').addEventListener('input', (e) => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(async () => {
const query = e.target.value;
if (query.length >= 2) {
const results = await api.searchVideos(query);
displaySearchResults(results.data.videos);
}
}, 300); // Wait 300ms after user stops typing
});
9. Browser Console Testing
Test API calls directly in the browser console:
// Check authentication
api.isAuthenticated()
// Login
await api.login('username', 'password')
// Get videos
await api.getVideos({ page: 1 })
// Get current user
await api.getMyProfile()
// View stored token
localStorage.getItem('jwt_token')
// Clear token
api.clearToken()
10. Next Steps
- Read API_DOCUMENTATION.md for complete reference
- Check FRONTEND_BACKEND_INTEGRATION_GUIDE.md for advanced patterns
- Review example code in f_scripts/fe/js/api-helper.js
Support
If you encounter issues:
- Check browser console for errors
- Check Network tab to see API requests/responses
- Verify you're logged in:
api.isAuthenticated() - Check API documentation for correct parameters
Last Updated: January 2025