Getting Started - Java
An Analyser
configures the analysis session with the desired exercise and then
communicates with the API by sending images. In return, events are called
containing specific event data. Each analyser has listeners implemented that are
called on their respective event. Visit the Analyser and
Listener sections for more details.
A short guide
Make sure you have imported the package, especially if your IDE does not add imports automatically.
import ai.vay.client.*;
When you create an analyser instance, which also sets up the connection to the
server, you can pass an instance of the Listener
interface with
implementations for each event. Note that the callbacks for the events have a
default implementation, which allows you to only implement the callbacks that
are needed. An example of the implementation for the Listener can look as
follows:
class AnalyserListener implements Listener
{
AnalyserListener()
{
}
// If you want to visualize the keypoints, do it from here.
@Override
public void onPose(PoseEvent event)
{
// Get the points for each body point type
Map<BodyPointType, Point> points = event.getPose().getPoints();
// For example the left knee
Point pointLeftKnee =
event.getPose().getPoint(BodyPointType.LEFT_KNEE);
}
// Metric values can be analysed here.
@Override
public void onMetricValues(MetricValuesEvent event)
{
// Get the metric values
List<MetricValue> metricValues = event.getMetricValues();
}
// Feedback are received here.
@Override
public void onFeedback(FeedbackEvent event)
{
// Get a list of feedback
List<Feedback> feedbacks = event.getFeedbacks();
}
// Any logic that evaluates an activity can go here. An activity can either
// be an attempt or a repetition.
@Override
public void onActivity(ActivityEvent event)
{
Activity activity = event.getActivity();
if (activity instanceof Repetition)
{
// Count total repetitions
totalRepetitions += 1;
// Get the duration of the repetition
Duration duration =((Repetition) activity).getDuration();
// Get all feedback that occurred during this repetition
List<Feedback> feedbacks = activity.getFeedbacks();
}
else if (activity instanceof Attempt)
{
// Get all feedback that occurred during this attempt
List<Feedback> feedbacks = activity.getFeedbacks();
}
}
// Any logic that evaluates repetitions can go here.
//
// Note that the same information is provided here as in the ActivityEvent
// if the activity is a Repetition.
@Override
public void onRepetition(RepetitionEvent event)
{
// Count total repetitions
totalRepetitions += 1;
// Get the duration of the repetition
Duration duration = event.getRepetition().getDuration();
// Get all feedbacks that occurred during this repetition
List<Feedback> feedbacks = event.getRepetition().getFeedbacks();
}
// Analyse the occurred error here.
@Override
public void onError(ErrorEvent event)
{
// Get error type
ErrorType errorType = event.getErrorType();
// Get error text
String errorText = event.getErrorText();
}
// Information that the analyser has been stopped. This is the place where
// reconnection or disposing could be implemented.
@Override
public void onStop()
{
}
// When the session is configured and ready, the exercise including all
// metrics is received.
@Override
public void onReady(ReadyEvent event)
{
// Get the exercise name
String exerciseName = event.getExercise().getName();
// Get the exercise key
long exerciseKey = event.getExercise().getKey();
// Get the metrics
List<Metric> metrics = event.getExercise().getMetrics();
// Get session ID
String sessionId = event.getAnalyser().getSessionInformation().getSessionId();
}
// When the session state changes e.g. from POSITIONING to EXERCISING,
// the new state can be stored here
@Override
public void onSessionStateChanged(SessionStateChangedEvent event)
{
// Get the session state
SessionState sessionState = event.getSessionState();
}
// Here the state of the ENVIRONMENT and the LATENCY can be analysed.
@Override
public void onSessionQualityChanged(SessionQualityChangedEvent event)
{
// Get the session quality
SessionQuality sessionQuality = event.getSessionQuality();
}
}
Once the callbacks are defined, you can pass the instance of AnalyserListener
together with the server uri, which will automatically try to set up a
connection. The session is configured with the passed exerciseKey
if the
provided apiKey
is correct. Optionally, an external user ID may be passed.
String url = "rpcs://<hostname>:<port>"; // Url that will be provided.
String apiKey = "API-KEY"; // Api key for authentication.
long exerciseKey = 1; // Key of the exercise to analyse.
String userExternalId = "USER-ID"; // Optional user ID.
AnalyserListener analyserListener = new AnalyserListener();
Analyser analyser = null;
try
{
analyser = AnalyserFactory.createStreamingAnalyser(invalidUrl,
apiKey, exerciseKey, listener, userExternalId);
}
catch (Exception e)
{
// handle exception related to failed analyser creation
}
Once the analyser is created, images should be encoded as JPEG
(or PNG
). An
example code for JPEG
compression can be seen below.
byte[] getArrayFromBitmap(Bitmap bmp)
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 60, stream);
byte[] byteArray = stream.toByteArray();
bmp.recycle();
return byteArray;
}
The encoded image can be submitted for analysis at any time.
byte[] image = getArrayFromBitmap(bmp);
AnalyserInput input = AnalyserFactory.createInput(image);
analyser.enqueueInput();
Don't forget to stop the analyser, once you're done.
analyser.stop();