react-filerobot-media-annotator
v1.1.0
Published
An emendable web-based plugin that is used in annotating the media files (images & videos) with consideration of your media player's design/controls.
Downloads
9,318
Maintainers
Readme
React Filerobot Media Annotator
An emendable web-based plugin that is used in annotating the media files (images & videos) with consideration of your media player's design/controls.
Demo
TBD.....
Features
- ⏳ History management (Undo/Redo).
- 🎨 Image/Video Annotating & Drawing.
- 🧊 A variety of annotating shapes.
- 🏗️ Easy, Focused & Simple UI for better UX.
- ➕ Ability to customize.
- 🤹🏼 And more to discover by yourself...
Contents
Prerequisites
You have to install the following packages (if you haven't them installed in your project) as they are required as peer dependencies,
- react, react-dom >= v17.0.1
- styled-components >= 5.2.3",
- @scaleflex/ui >= 2.0.0-beta.40
- @scaleflex/icons >= 2.0.0-beta.36
- reactjs-eventemitter >= 1.0.6
- react, react-dom:
npm install --save react react-dom
. - styled-components:
npm install --save styled-components
. - scaleflex/ui, @scaleflex/icons:
npm install --save @scaleflex/ui @scaleflex/icons
. - reactjs-eventemitter:
npm install --save reactjs-eventemitter
.
Installation
NPM
npm install --save react-filerobot-media-annotator
Usage/Examples
React Example
import React, { useRef } from 'react';
import {
Canvas,
AnnotatingField,
Comments
} from 'react-filerobot-media-annotator';
import translations from './translations';
import {
createCommentRequest, deleteCommentsRequest, dislikeCommentRequest, editCommentTextRequest,
fetchCommentsRequest, likeCommentRequest, subscribeToCommentRequest,
unsubscribeToCommentRequest,
} from './services';
const Annotator = ({ config }) => {
const mediaRef = useRef(null);
const rootContainerRef = useRef(null);
//First of all we need to map the fetched comment to the plugin comments format!
const getFormattedComment = (fetchedComment) => ({
id: fetchedComment.id,
shapes: fetchedComment.shapes || [],
user: {
id: fetchedComment.user.id,
name: fetchedComment.user.userName,
photo_uri: fetchedComment.user.photo,
},
createdAt: fetchedComment.createdAt,
body: fetchedComment.body,
meta: {
likers: fetchedComment.meta.likers || [],
subscribers: fetchedComment.meta.subscribers || [],
resolved: fetchedComment.meta.resolved || false,
canvasDimensions: fetchedComment.meta.canvasDimensions,
displayTimeStamp: fetchedComment.meta.displayTimeStamp || null,
}})
//Then fetch the backend comments and get our mapped comments!
const getComments = () => (
//do not forget to import your fetchCommentRequest function!
fetchCommentsRequest().then(({ comments: fetchedComments = [] }) => {
const updatedComments = fetchedComments.map((fetchedComment) => {
return getFormattedComment(fetchedComment)
});
return updatedComments;
})
);
//We need a way to handle our various updates! here we used actions object
//you can handle the updateComment function they way you prefer ⚡
//do not forget to import your commentRequests or equivalent logic functions!
const ACTIONS = {
[ACTIONS_IDS.TOGGLE_LIKE || 'toggleLike']: {
action: (updatedComment, updates) => {
const newLikers = updates;
if (newLikers.includes(config.currentUserId)) {
return likeCommentRequest(updatedComment.id).then((res) => (res));
}
return dislikeCommentRequest(updatedComment.id).then((res) => (res));
},
},
[ACTIONS_IDS.TOGGLE_SUBSCRIBE || 'toggleSubscribe']: {
action: (updatedComment, updates) => {
const newSubscribers = updates;
if (newSubscribers.includes(config.currentUserId)) {
return subscribeToCommentRequest(updatedComment.id).then((res) => (res));
}
return unsubscribeToCommentRequest(updatedComment.id).then((res) => (res));
},
},
[ACTIONS_IDS.UPDATE_COMMENT_PROPS || 'updateCommentProps']: {
action: (updatedComment, updates) => {
const newResolve = updates;
return editCommentTextRequest(updatedComment.id, {resolved: newResolve});
},
},
[ACTIONS_IDS.UPDATE_COMMENT_TEXT || 'updateCommentText']: {
action: (updatedComment, updates) => {
const newText = updates;
return editCommentTextRequest(updatedComment.id, { text: newText });
},
},
};
const updateComment = ({ actionId, updatedComment, updates }) => (
ACTIONS?.[actionId]?.action(updatedComment, updates)
);
//We need a function to handle submitting of new comment then returning new, mapped comment
// do not forget to import your createCommentRequest function!
const onSubmitComment = (newCommentProps) => createCommentRequest(newCommentProps)
.then((newComment) => {
return getFormattedComment(newComment)
});
//Also a function to handle replying to comment then returning new, mapped comment
// do not forget to import your createReplyRequest function!
const createReply = (newCommentProps) => createReplyRequest(newCommentProps)
.then((newComment) => {
return getFormattedComment(newComment)
});
//Finally, we need a function to handle delete comment and then return the new Comments!
// do not forget to import your deleteCommentsRequest function!
const deleteComment = (commentId) => (
deleteCommentsRequest([commentId]).then(() => (
getComments().then((newComments) => (newComments))
))
);
return (
<div ref={rootContainerRef}>
<video
ref={mediaRef}
muted
>
<track src={'http://www.w3schools.com/html/mov_bbb.mp4'} />
<source src={'captions_en.vtt'} />
</video>
<Canvas
isVideoShapesAutoStreamed={true}
mediaRef={mediaRef}
shapeStreamingDuration={1000}
/>
<AnnotatingField
annotatingTools={['Color', 'Brush', 'Circle', 'Square', 'Line', 'Arrow']}
translations={translations}
onSubmit={onSubmitComment}
/>
<Comments
isVideoAutoPlayed
translations={translations}
getComments={getComments}
createReply={createReply}
updateComment={updateComment}
deleteComment={deleteComment}
currentUserId={currentUserId}
/>
</div>
);
};
export default Annotator;
Config
NOTE: The plugin respects the container/wrapper HTML element through CSS by having both
width
&height
set100%
so you could change the width/height of the plugin through adding/changing width/height of the wrapper HTML element.
Properties
theme
Type: object
Supported version: +v0.1.0
Default: {}
.
Defines the theme used in the plugin, utilized by @scaleflex/ui
library, u'll find the theme object form here.
currentUserId
Type: string
Supported version: +v0.1.0
Default: undefined
.
The id of the current user using the plugin.
annotatingTools
Type: array
Supported version: +v0.1.0
The tools and shapes used to annotate shapes on media, available tools are [Color, Brush, Circle, Square, Line, Arrow], if not supported all of them will be used
shapeStreamingDuration
Type: number
Supported version: +v0.1.0
Default: 1000
.
The duration in milliseconds which the shape will be streamed until and then removed.
isVideoAutoPlayed
Type: boolean
Supported version: +v0.1.4
Default: true
.
The flag to stream the play the loaded video automatically after comments loads.
isVideoShapesAutoStreamed
Type: boolean
Supported version: +v0.1.0
Default: true
.
The flag to stream the shapes automatically on video play or just by clicking on comment.
translations
Type: object
Supported version: +v0.1.0
Default: undefined
.
Translations keys and equivalent string supported to the plugin, if not supported the plugin will use the default keys as displayed in the following table see available translations
getComments
Type: async function
Supported version: +v0.1.0
Backend request function to get comments mapped to our comment object.
createReply
Type: async function
Supported version: +v0.1.0
Backend request function to reply to comment and get the new comments mapped to our comment object.
updateComment
Type: async function
Supported version: +v0.1.0
Backend request function to update comment.
deleteComment
Type: async function
Supported version: +v0.1.0
Backend request function to delete comment.
Development
To run in development mode, follow the next steps:
- Clone the repository.
- Open the repository's folder & run
yarn
to install the project's dependencies. - Run
yarn dev
to start the project in development. - Happy coding🕺🏽!
Used By
This project is used by the following companies:
Fork the repoistory, append your company's name with the URL in above format inside the README.md file and make a PR! or create a GitHub issue mentioning (Site's name & domain).
Feedback
Create an issue on github repo. and mention the details there.
Contributing
All contributions are super welcomed!
License
Filerobot Image Editor is provided under MIT License